分布式搜索引擎Elasticsearch——基础

文章目录

一、Lucene与Solr与Elasticsearch

  • Lucene是java的类库,本质上是个jar包
  • Solr是基于Lucene封装的,可以通过zk进行集群,可以实现分布式负载均衡、自动故障转移,可靠性和容错性还是很高的
  • Elasticsearch也是基于Lucene的,想对于Solr更快,支持TB基本的大数据查询,实时性更高
    es官网:https://www.elastic.co/cn/

二、ES核心术语

术语名英文名解释
索引index相当于数据库的表
类型type相当于表的逻辑类型(新版本中已经不再使用)
文档document相当于行,一条数据
字段fields相当于列,一个属性

三、ES核心概念

概念名英文名解释
映射mapping表结构定义
近实时NRT(Near real time)当创建文档或者索引的时候 并不是完全实时的,会有一个1秒左右的延迟,所以叫近实时
节点node每一个服务器都是一个节点
数据分片shard把索引库拆分为多份,分别放在不同的节点上,比如有3个节点,3个节点的所有数据内容加在一起是一个完整的索引库。分别保存到三个节点上,目的为了水平扩展,提高吞吐量。
备份replica每个shard的备份,当节点上的主分片(shard)挂掉之后,replica会负责容错,以及承担读请求负载(replica不应当和shard放在同一个服务器上,否则节点宕机,shard和replica都丢失,起不到容错的作用)

四、倒排索引

了解倒排索引之前先要了解正排索引,如下:

文档id文档内容
1QQ是常用的聊天软件
2用QQ进行聊天
3常用的聊天软件有QQ

正排索引就是通过索引id可以找到对应的内容,倒排就是相反的通过内容的片段可以找到对应的索引,然后再找到文件内容,如下:

单词文档ids词频TF:位置POS (下面的格式的意思是 id:出现的次数:<单词在文档中出现的位置索引>)
QQ1,2,31:1:<1>,2:1:<2>,3:1<8>
常用的1,2(下面不再举例了)…
聊天1,2,3
软件1,3
聊天软件1,3
进行2
1,2,3
3

  在搜索引擎中每个文件都对应一个文件ID,文件内容被表示为一系列关键词的集合(实际上在搜索引擎索引库中,关键词也已经转换为关键词ID)。例如上面的例子经过分词,提取了8个关键词,每个关键词都会记录它在文档中的出现次数和出现位置。
  倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表的每一项,都包括一个属性值和包含该属性值的各个记录地址。由于不是根据记录来确定属性,而是根据属性来确认记录的位置,所以称之为倒排索引。

五、ES的安装(centos7)

1、下载地址(这里安装linux版本)

https://www.elastic.co/cn/downloads/elasticsearch

2、解压压缩包

#解压到/usr/local/目录下
tar -zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz -C /usr/local/
#进入解压的目录
cd /usr/local/elasticsearch-7.4.2
#添加l两个文件夹 用于以后做数据和日志存放目录
mkdir data
mkdir logs

3、修改配置文件

(1)修改核心配置文件

核心配置是es根目录下config文件夹里的elasticsearch.yml

#打开核心配置文件
vim elasticsearch.yml
#集群名称,单节点也是可以定义
cluster.name: keyboard-dog-elasticsearch
#节点名称
node.name: es-node1
#数据存放路径
path.data: /usr/local/elasticsearch-7.4.2/data
#日志存放路径
path.logs: /usr/local/elasticsearch-7.4.2/logs

#绑定可以操作的地址 0.0.0.0表示所有的ip地址都可以访问操作
network.host: 0.0.0.0
#用于访问的端口
http.port: 9200
#添加跨域配置
http.cors.enabled: true
#可以跨域的地址
http.cors.allow-origin: "*"

#设置一系列符合主节点条件的节点的主机名或 IP 地址来引导启动集群
#这里的es-node1是在上面配置过了
cluster.initial_master_nodes: ["es-node1"]
(2)修改JVM配置文件

JVM配置是es根目录下config文件夹里的jvm.options

#打开核心配置文件
vim jvm.options
#在虚拟机或者自己学习的时候把jvm的初始化和最大堆空间修改小一点
#生成环境可以根据机器配置适量增大或减少
-Xms128m
-Xmx128m

4、启动ES

(1)添加系统用户并授权

ES默认是禁止root用户启动的,所以需要添加一个用户

#添加一个名叫esuser系统用户
useradd esuser
#进行授权
chown -R esuser:esuser /usr/local/elasticsearch-7.4.2
#切换到esuser用户
su esuser
(2)ES启动
#进入bin目录
cd bin
#启动ES
./elasticsearch

启动的时候会返现出现错误

ERROR: [3]bootstrap checks failed
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
[2]: max number of threds [3756] for user [esuser] is too low, increase to at least[4096]
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

第一个问题的意思是:ES能打开的文件数量太少了 要提升
第二个问题的意思是:esuser能使用的最大线程数太少了,也需要提升
第三个问题的意思是:虚拟内存的最大值太低了
这些问题主要是系统配置上的问题,需要修改系统配置文件

(3)修改配置文件
#切换到root用户
su root
#修改系统安全限制配置文件
vim /etc/security/limits.conf

翻到文件最下方,添加如下内容

#soft代表警告的设定,可以超过这个设定值,但是超过后会有警告
#hard代表严格的设定,不允许超过这个设定的值
#nofile是每个进程可以打开的文件数的限制
#nproc是操作系统级别对每个用户创建的进程数的限制
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096

保存并退出,再修改系统控制配置

#修改系统控制配置
vim /etc/sysctl.conf

在文件最下方添加配置

vm.max_map_count=262145

保存并退出,然后刷新配置文件

sysctl -p
(4)再次启动ES

切换回esuser用户

su esuser

切换到ES的bin目录启动ES

#前台启动的方式
./elasticsearch

#后台启动的方式
./elasticsearch -d

通过访问ip:9200可以查看es的相关配置

端口号意义

  • 9200:Http协议,用于外部通讯
  • 9300:Tcp协议,ES集群之间是通过9300通讯

六、安装ES-head插件(可视化管理插件)

1、使用谷歌市场安装ES-head插件

(1)使用科学上网
(2)访问谷歌应用商店

https://chrome.google.com/webstore/category/extensions?hl=zh-CN

(3)搜索并安装ElasticSearch Head
(4)在工具栏右上角点击多出来的按钮,打开ES-header

2、使用源码方式安装ES-head插件

(1)下载ES-head源码
git clone git://github.com/mobz/elasticsearch-head.git
(2)安装node.js
  1. 下载地址:nodejs.cn/download
  2. 下载windows安装包
  3. 打开安装包直接下一步下一步
  4. 验证安装是否成功,打开cmd
node -v
npm -v
(2)使用npm编译源码

打开cmd并进入ES–head的源码目录

npm install
(3)运行ES-head
npm run start
(4)解决跨域问题

在ES的核心配置文件里面添加跨域配置
上面已经设置过了,如果你无法连接,回头再看一下
设置之后记得重启一下ES

(5)打开访问页面

http://localhost:9100/

七、ES基于Head和restful Api的基本操作

主要数据类型

  • 字符串类型 string,text,keyword
  • 整数类型 integer,long,short,byte
  • 浮点类型 double,float,half_float,scaled_float
  • 逻辑类型 boolean
  • 日期类型 date
  • 范围类型 range
  • 二进制类型 binary
  • 数组类型 array
  • 对象类型 object
  • 嵌套类型 nested
  • 地理坐标类型 geo_point
  • 地理地图 geo_shape
  • IP类型 ip
  • 范围类型 completion
  • 令牌计数类型 token_count

在Elasticsearch中,数组不需要一个特定的数据类型,任何字段都默认可以包含一个或多个值,当然,这多个值都必须是字段指定的数据类型

text:文字类需要被分词被倒排索引的内容,比如商品名称,商品详情,商品介绍,使用text。
keyword:不会被分词,不会被倒排索引,直接匹配搜索,比如订单状态,用户qq,微信号,手机号等,这些精确匹配,无需分词。

1、创建新的索引

(1)使用Head创建索引

1)打开es-head
2)点击table页的索引栏
3)点击新建索引

  • 索引名称:当前索引的名称
  • 分片数:所有数据的文件块,也是数据的最小单元块,所有的时间会被尽量的平分在所有分片里
  • 副本数 备份分片的数量,是为每一个分片提供的副本数量

这里我们把分片数设置5,占时不需要副本,副本数设置为0,索引名随意,我设置为index_demo

(2)使用api创建索引

使用put请求访问 ip:9200/索引名
在body中添加分片数和副本数信息

{
    "setting": {
        "index": {
            "number_of_shards": "2",
            "number_of_replicas": "0"
        }
    }
}

创建的同时定义字段类型(mappings自定义映射)

{
    "mappings": {
        "properties": {
        <!-- 定义一个叫“realname”的字段,类型为字符串,并且被索引 -->
            "realname": {
                "type": "text",
                "index": true
            },
            <!-- keyword类型的字段是不会被分词的,只能被精确查询 -->
            "username": {
                "type": "keyword",
                "index": flase
            }
        }
    }
    "setting": {
        "index": {
            "number_of_shards": "2",
            "number_of_replicas": "0"
        }
    }
}

2、查看索引健康情况

(1)使用Head查看健康情况

1)刷新一下页面,进入概览
  可以看到新建索引的情况,有从0到4五个分片,都是绿色的 说明情况良好,在页面的最顶端还能看见有绿地黑字的文字“集群监控值:green(5 of 5)”表示一共5个分片 5个分片情况良好
2)再次新建索引
  这次我们把分片数设置5,副本数设置为1,为每一个分片添加1个副本,索引名随意’
3)查看健康状况
  健康状况变成了黄色底:“集群健康值: yellow (10 of 15)
  点击概览,可以看到新建索引的副本都是灰色的,这是因为副本不会被和分片放在同一个节点上,而我们的es只有一个节点

4)健康状况说明
官方文档:https://www.elastic.co/guide/en/elasticsearch/guide/current/_cluster_health.html

  • green:所有主要和副本碎片均已分配。您的集群可以100%运行。
  • yellow:所有主分片均已分配,但至少缺少一个副本。没有数据丢失,因此搜索结果仍将是完整的。但是,您的高可用性在一定程度上受到了损害。如果更多碎片消失,则可能会丢失数据。可以将其yellow视为应该立即进行调查的警告。
  • red:至少缺少一个主分片(及其所有副本)。这意味着您缺少数据:搜索将返回部分结果,而对该分片建立索引将返回异常。
(2)使用api查询集群健康情况

使用get请求访问 ip:9200/_cluster/health

3、删除索引

(1)使用Head删除索引

1)打开es-head
2)进入概览
3)选择对应索引的动作按钮
4)点击删除
5)在弹出框中输入删除,点击确定,成功删除

(2)使用api删除索引

使用delect请求访问 ip:9200/删除的索引名

4、查看分词效果

(1)使用api查看分词效果

使用get请求访问 ip:9200/索引名/_analyze
添加body

{
    <!-- 使用默认的分词器查看字段realname值为so good时候的分词结果 -->
    "analyzer": "standard",
    "field": "realname",
    "text":"so good!"
}

5、为已存在的索引创建mappings

(1)使用api新增mappings

使用post请求访问 ip:9200/索引名/_mapping
添加body

"properties": {
    "name": { 
        "type": "long" 
     }
}

注:某个属性一旦被建立,就不能修改了,但是可以新增额外属性

6、添加文档

使用post请求访问 ip:9200/索引名/_doc/[id]
添加body

{ 
    "id": 1001, 
    "name": "test-1", 
    "desc": "这个文档写的真是太好了", 
    "create_date": "2019-12-24"
}

注:如果索引没有手动建立mappings,那么当插入文档数据的时候,会根据文档类型自动设置属性类型。这个就是es的动态映射,帮我们在index索引库中去建立数据结构的相关配置信息

  • “fields”: {“type”: “keyword”}
    对一个字段设置多种索引模式,使用text类型做全文检索,也可使用keyword类型做聚合和排序
  • “gnore_above” : 256
    设置字段索引和存储的长度最大值,超过则被忽略

7、删除文档

使用delete请求访问 ip:9200/索引名/_doc/[id]

8、修改文档

(1)属性部分修改

使用post请求访问 ip:9200/索引名/_doc/[id]/_update
添加body,修改name属性

{
    "doc":{
        "name": "我现在是一个新的name了"
    }
}
(2)属性全量修改

使用put请求访问 ip:9200/索引名/_doc/[id]
添加body

{ 
    "id": 1, 
    "name": "test-2", 
    "desc": "这个文档写的真是太好了!!!", 
    "create_date": "2019-12-25"
}

9、根据id查询文档

使用get请求访问 ip:9200/索引名/_doc/[id]

10、查询所有的文档

使用get请求访问 ip:9200/索引名/_doc/_search

11、根据id查询文档是否存在

使用head请求访问 ip:9200/索引名/_doc/[id]

八、文档的乐观锁

  当查询、插入、更新一条数据的时候都能看到有一个_version属性,这个属性标识当前数据的版本号,老版本中通过这个属性实现乐观锁,只需要在请求最后加上版本号就可以了
使用post请求访问 ip:9200/索引名/_doc/[id]/_update?version={数值}
但是在新版本中,这个方法已经被淘汰了,采用_seq_no和_primary_term来实现乐观锁
使用post请求访问 ip:9200/索引名/_doc/[id]/_update?if_seq_no={数值}&if_primary_term={数值}

  • _seq_no:文档版本号,作用同_version(文档所有位置内部的编号,效率更加高效,管理起来更方便)
  • _primary_term:文档所在位置

九、分词器

1、什么是分词器

  把文本转换为一个个的单词,分词称之为analysis。es默认只对英文语句做分词,中文不支持,每个中文字都会被拆分为独立的个体。

2、es内置分词器

  • standard:默认分词,单词会被拆分,大小会转换为小写。
  • simple:按照非字母分词。大写转为小写。
  • whitespace:按照空格分词。忽略大小写。
  • stop:去除无意义单词,比如the/a/an/is…
  • keyword:不做分词。把整个文本作为一个单独的关键词。

3、中文ik分词器

github官网地址:https://github.com/medcl/elasticsearch-analysis-ik

(1)安装

手动安装

  1. 从github上下载压缩包
    https://github.com/medcl/elasticsearch-analysis-ik/releases
  2. 进入ES根目录下的plugins文件夹
  3. 创建一个叫ik的文件夹
  4. 将压缩包里的内容解压到ik文件夹下
  5. 重启ES

自动安装
自动安装ES的版本必须高于5.5.1

  1. 进入ES的根目录,下载插件
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip
  1. 重启ES(别忘记切换用户)
(2)ik中的两种分词器

ik_max_word
  会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;

ik_smart
  会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。

(3)自定义中文分词库

  中文词汇复杂繁多,ik分词器也不能保证所有情况下都能有效的分词,例如:“骚年在认真的学习”,就会被拆分成“骚,年在,认真的,学习”,很明显“年在”并不是一个词,同样的一些专属名词也不能很有效的分词,比如:“印象笔记”,“掘金网“等等,这时候我们就需要为分词器,添加自定义词汇。

  1. 修改ik分词器配置文件、添加自定义词典
    进入ES根目录,修改ik分词器的词典配置(别忘记切换用户,使用root)
vim plugins/ik/config/IKAnalyzer.cfg.xml

在ext_dict属性中添加自定义的词典,需要添加多个字典用分号隔开“;”

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">custom.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!--<entry key="remote_ext_dict">location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!--<entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry> -->
</properties>
  1. 在这个目录下新建一个文件名叫custom.dic,并添加如下内容
骚年
印象笔记
掘金网
  1. 重启ES(别忘记切换用户,使用esuser)

十、DSL搜索详解

语法格式为一个json object,内容都是key-value键值对,json可以嵌套。key可以是一些es的关键字,也可以是某个field字段,后面会遇到

(1)根据字段值查询

使用post请求访问 ip:9200/索引名/_doc/_search
body:

{ 
    "query": { 
        "match": { 
            <!-- 查询desc属性里包含掘金网的数据 -->
            "desc": "掘金网" 
        }
    }
}
(2)判断某个字段是否存在

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "exists": { 
            "field": "desc" 
        } 
    } 
}
(3)自定义查询字段(_source)

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        <!-- 查询所有的意思 -->
        "match_all": {} 
    } ,
    
    <!-- 设定要查询的属性,注意这里使用的是中括号 -->
    "_source": [
        "id",
        "name",
        "age"
    ]
}
(4)分页查询(from、size)

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        <!-- 查询所有的意思 -->
        "match_all": {} 
    } ,
    <!-- 从第10条开始查询 -->
   "from":10,
   <!-- 查询后续的10条 -->
   "size":10
  
}
  • from 查询起始位置
  • size 查询数据的条数
(5)关键词查询(term)

使用term查询的时候,关键词不会被拆分,例如:查询“掘金网”,“掘金网”会被作为一个整体在库中查询,不会拆分成“掘金”、“掘”、“金”、“网”之类的分词进行查询
使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "term": {
            "desc": "掘金网"
        } 
    } 
}

多个关键词查询

{ 
    "query": { 
        "term": {
            "desc": ["掘金网","骚年"]
        } 
    } 
}
(6)分词查询(match)

使用match查询的时候,关键词会被拆分,例如:查询“掘金网”,会拆分成“掘金”、“掘”、“金”、“网”之类的分词进行查询。
当operater为or的时候(默认为or),只要命中一个拆分的词汇时就可以当做匹配,设置为and的时候,必须所有的分词都匹配到。
  minimum_should_match: 最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。同时也支持设置具体的数字,表示匹配单词的个数
使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "match": {
            "desc": "掘金网",
            <!-- 可以设置or或者and -->
            "operator": "or",
            "minimum_should_match": "60*"
        } 
    } 
}
(7)短语匹配(match_phrase)

  就像用于全文搜索的的match查询一样,当你希望寻找邻近的单词时,match_phrase查询可以帮你达到目的,和match查询类似,match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。例如:搜索"大学 毕业",那么数据必须包含“大学”和“毕业”两个单词,并且是连在一起的才会被搜索到。
  我们也可以使用“slop”属性指定允许的间隔数,意思是“大学”和“毕业”之间可以出现其他词汇的数量,设置2,就允许中间出现1个或者2个单词,设置100就允许中间至多有100个词汇
使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "match_phrase": {
            "desc": {
                "query": "大学 毕业", 
                "slop": 2
            }
        } 
    } 
}
(8)主键ids匹配

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "ids": {
            "type": "_doc", 
            "values": ["1001", "1010", "1008"]
        } 
    } 
}
(9)多属性查询(multi_match)

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "multi_match": {
            "query": "皮特帕克",
            <!-- 在desc和name属性中匹配皮特帕克 -->
            "fields": ["desc", "name"]
        } 
    } 
}

可以使用"^数字"的方式对属性添加权重,例如我们给name属性添加权重,这样搜索的时候name中出现匹配关键词的数据就会显示在前面

{ 
    "query": { 
        "multi_match": {
            "query": "皮特帕克",
            <!-- 在desc和name属性中匹配皮特帕克 -->
            "fields": ["desc", "name^10"]
        } 
    } 
}
(10)布尔查询

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "bool": {
            <!-- 这里是多重查询的判断条件,可以使用 
                must:查询必须匹配搜索条件,譬如 and
                should:查询匹配满足1个以上条件,譬如 or
                must_not:不匹配搜索条件,一个都不要满足
              -->
            "must": [ 
                { 
                    <!-- 这里和普通查询就没区别了 -->
                    "multi_match": { 
                        "query": "掘金网", 
                        "fields": ["desc", "name"]
                    }
                }, { 
                    "term": { 
                        "sex": 1 
                        <!-- 添加权重 -->
                        "boost": 18
                     }
                 }, { 
                    "term": { 
                        "birthday": "1996-01-14" 
                    }
                } 
            ]
            <!-- 这里继续添加不同的多重查询判断条件也是可以的 -->
        } 
    } 
}
(11)前缀查询(prefix)

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        <!-- 查询name属性以皮特帕克开始的数据 -->
        "prefix": {
            "name": "皮特帕克"
        } 
    } 
}
(12)模糊查询(fuzzy)

模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。
官方文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/fuzzy-match-query.html
使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        <!-- 模糊查询 -->
        "fuzzy": {
            "desc": "骚年"
        } 
    } 
}

多字段查询

{ 
    "query": { 
        <!-- 模糊查询 -->
        "multi_match": {
            "fields": [ "desc", "name"], 
            "query": "骚年", 
            "fuzziness": "AUTO"
        } 
    } 
}
(13)占位符查询(wildcard)

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "wildcard": {
            <!-- *表示可以有多个字符
                  ?表示只有一个字符
            -->
            "name": "*皮特帕克?"
        } 
    } 
}
(14)过滤器

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "match": { 
            <!-- 查询desc属性里包含掘金网的数据 -->
            "desc": "掘金网" 
        }
    },
    <!-- 过滤器 -->
    "post_filter": { 
        "range": { 
            <!-- 过滤的字段 -->
            "money": { 
                <!-- 取大于60并且小于1000的数据
                    gte:大于等于
                    lte:小于等于
                    gt:大于
                    lt:小于
                -->
                "gt": 60, 
                "lt": 1000 
            } 
        } 
    }
}
(15)排序

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "match": { 
            <!-- 查询desc属性里包含掘金网的数据 -->
            "desc": "掘金网" 
        }
    },
    <!-- 排序  test类型的属性是没法排序的-->
    "sort": [ 
        { 
            <!-- desc降序排序,asc升序排序 -->
            "age": "desc"
        }, { 
            "money": "desc" 
        } 
    ]
}

由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。
test属性增加keyword创建索引的方法,使用post请求访问 ip:9200/索引名/_mapping

{ 
    "properties": { 
        "id": { 
            "type": "long" 
        },
        "name": { 
            "type": "text", 
            "analyzer": "ik_max_word", 
            "fields": { 
                "keyword": { 
                    "type": "keyword" 
                }
            }
        }
    }
}

在排序的时候使用name下的keyword属性排序,有点内部类的感觉

{
    "sort": [ 
        { 
            "name.keyword": "desc"
        }
    ]
}
(16)查询高亮

使用post请求访问 ip:9200/索引名/_doc/_search

{ 
    "query": { 
        "match": { 
            <!-- 查询desc属性里包含掘金网的数据 -->
            "desc": "掘金网" 
        }
    },
    <!-- 高亮关键词 -->
    "highlight": { 
        <!-- 在关键词前面 添加tag标签,默认为em标签 -->
        "pre_tags": ["<tag>"], 
        <!-- 在关键词后面 添加tag标签,默认为em标签 -->
        "post_tags": ["</tag>"], 
        <!-- 需要高亮的属性 -->
        "fields": { 
            "desc": {}
         } 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值