文章目录
一、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 | 文档内容 |
---|---|
1 | QQ是常用的聊天软件 |
2 | 用QQ进行聊天 |
3 | 常用的聊天软件有QQ |
正排索引就是通过索引id可以找到对应的内容,倒排就是相反的通过内容的片段可以找到对应的索引,然后再找到文件内容,如下:
单词 | 文档ids | 词频TF:位置POS (下面的格式的意思是 id:出现的次数:<单词在文档中出现的位置索引>) |
---|---|---|
1,2,3 | 1: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
- 下载地址:nodejs.cn/download
- 下载windows安装包
- 打开安装包直接下一步下一步
- 验证安装是否成功,打开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)安装
手动安装
- 从github上下载压缩包
https://github.com/medcl/elasticsearch-analysis-ik/releases - 进入ES根目录下的plugins文件夹
- 创建一个叫ik的文件夹
- 将压缩包里的内容解压到ik文件夹下
- 重启ES
自动安装
自动安装ES的版本必须高于5.5.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
- 重启ES(别忘记切换用户)
(2)ik中的两种分词器
ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
(3)自定义中文分词库
中文词汇复杂繁多,ik分词器也不能保证所有情况下都能有效的分词,例如:“骚年在认真的学习”,就会被拆分成“骚,年在,认真的,学习”,很明显“年在”并不是一个词,同样的一些专属名词也不能很有效的分词,比如:“印象笔记”,“掘金网“等等,这时候我们就需要为分词器,添加自定义词汇。
- 修改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>
- 在这个目录下新建一个文件名叫custom.dic,并添加如下内容
骚年
印象笔记
掘金网
- 重启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": {}
}
}
}