1. 数据准备
- 1.1 先新建索引index,索引名称:shop
- 1.2 添加以下字段
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word"
},
"money": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"birthday": {
"type": "date"
},
"face": {
"type": "text",
"index": false
}
}
}
HTTP POST请求创建以上字段
POST /shop/_mapping HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 654
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word"
},
"money": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"birthday": {
"type": "date"
},
"face": {
"type": "text",
"index": false
}
}
}
- 1.3 添加测试数据
HTTP POST请求
POST /shop/_doc/1001 HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 335
{
"id": 1001,
"age": 18,
"username": "zhangsan",
"nickname": "张三",
"money": 199.8,
"desc": "我是张三,我现在在学习Elasticsearch",
"sex": 0,
"birthday": "2003-09-01",
"face": "http://www.imooc.com/static/img/index/logo.png"
}
完整的post请求链接为:http://192.168.10.235:9200/shop/_doc/1001
链接末尾的1001与json中的id:1001最好对应上。
按此格式,添加多条用于测试的数据即可。
2. 简单数据查询
- 2.1 GET 请求查询数据(无条件,查询全部)
http://192.168.10.235:9200/shop/_search
- 2.2 GET 请求查询数据(添加查询条件)
一个查询条件
http://192.168.10.235:9200/shop/_search?q=nickname:张三
多个查询条件
http://192.168.10.235:9200/shop/_search?q=nickname:张三&q=desc:学习
- 2.3 POST 请求查询数据
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 79
{
"query": {
"match": {
"nickname": "张三"
}
}
}
post请求链接固定:http://192.168.10.235:9200/shop/_search
搜索条件写在json中,match为es中的关键字,如果你写错,执行请求就会报错。
3. DSL搜索-全部查询、分页查询
- 3.1 GET 请求
http://192.168.10.235:9200/shop/_search
- 3.2 POST 请求,使用es关键字 match_all
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 48
{
"query": {
"match_all": {}
}
}
查询全部建议使用post方式,因为后期如果需要添加分页、过滤等功能,get请求链接会越来越复杂。
- 3.3 只返回指定字段,使用 _source
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 120
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
]
}
这样查询结果就只会返回 id、nickname、age 三个指定的字段。
- 3.4 分页查询,使用 from、size
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 151
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
],
"from": 0,
"size": 10
}
from:从第几条数据开始
size:一页返回多少条数据
4. DSL搜索-不进行分词搜索 term
match在查询时,是进行了分词的操作
而term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 77
{
"query": {
"term": {
"desc": "学习"
}
}
}
搜索在desc中包含 “学习” 的数据
如果需要匹配多个词,则可以使用 terms
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 77
{
"query": {
"terms": {
"desc": ["在","学习"]
}
}
}
5. DSL搜索-临近搜索词 match_phrase
现在有两条数据,desc 分别为:
第一条:“你大学已经毕业了吗?”
第二条:“我在大学毕业后,考研究生去了”
现在使用 match_phrase 来进行查询
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 129
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业"
}
}
}
}
此时只能查询出来第二条数据,第一条数据是匹配不到的,
match_phrase 要求 大学 的后面,必须是 毕业 两个字,只有满足“大学毕业”的才算符合条件;
那怎样才能同时查询出第一条和第二条数据呢
可以使用关键字 slop,即中间跳过一定的字符
比如第一条 大学 和 毕业 中间隔了两个字符,使用 "slop": 2
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 156
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业",
"slop": 2
}
}
}
}
只要 slop 大于等于2,两条数据都能查询出来。
关于 match_phrase 具体解释和用法,也可以看官方文档 短语匹配
5. DSL搜索-操作符 operator
先看请求
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 154
{
"query": {
"match": {
"desc": {
"query": "在学习",
"operator": "or"
}
}
}
}
我们知道 match 会进行分词操作,在查询时,会将 “在学习” 分成 “在” 和 “学习” 两个词进行检索匹配
使用or,则会查询出在desc中包含 “在” 或包含 “学习” 的数据
如果使用 and ("operator": "and"),则只会查询出在desc中包含 “在学习” 的数据
如果 query 条件是一句话,比如:“让开发者成为一个令人尊敬的职业”,此时则会分词成很多个词,匹配到的数据也有很多,使得查询精度不够高,
这时就可以使用 minimum_should_match 来提高匹配精度。
我们先看看es会将 “让开发者成为一个令人尊敬的职业” 这一句话分成多少个词?
POST /_analyze HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 64
{
"analyzer": "ik_max_word",
"text": "让开发者成为一个令人尊敬的职业"
}
查询结果显示是分成了 13 个词,所以如果是直接去匹配的话,则会查询出来很多数据
minimum_should_match 代表最小被匹配到的
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 167
{
"query": {
"match": {
"desc": {
"query": "让开发者成为一个令人尊敬的职业",
"minimum_should_match": "60%"
}
}
}
}
这里 60% 则表示,搜索结果要满足 13 个词的60%(含)以上,即 13*0.6=7.8,向下取整为7
需要包含7个(包括7)以上的词,而不是只包含其中的一个词。
这里不仅可以写百分比,也可以直接写数字,比如:"minimum_should_match": "3"
则表示是包含 3 个(包括3)词以上的
6. DSL搜索-根据id查询数据 ids
这个比较简单,使用关键字 ids 即可,可以查询多个
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 164
{
"query": {
"ids": {
"type": "_doc",
"values": [
"1001",
"1006"
]
}
}
}
values数组中填写要查询的id就行。
7. DSL搜索-多重查询 multi_match 和提高指定字段权重
多重查询的意思就是使用多个字段去做查询
现在有这两条数据:
我要查询 nickname 和 desc 都包含 沙僧 的数据
使用关键字 multi_match
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 175
{
"query": {
"multi_match": {
"query": "沙僧",
"fields": [
"nickname",
"desc"
]
}
}
}
提高指定字段的权重,使用 ^
比如我要提高nickname在查询中的权重,则只需要在 nickname 后加上 ^数字
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 175
{
"query": {
"multi_match": {
"query": "沙僧",
"fields": [
"nickname^10",
"desc"
]
}
}
}
这样查询出来的结果排序和默认的则不一样了。
而且返回的数据中 max_score 和 _score 的值也有变化
7. DSL搜索-组合查询 bool
将多个条件组合在一起
- 7.1 must:是指要同时满足下面的两个条件
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 481
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "沙僧",
"fields": [
"nickname",
"desc"
]
}
},
{
"term": {
"sex": 0
}
}
]
}
}
}
- 7.2 should:下面的两个条件,满足一个就行
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "沙僧",
"fields": [
"nickname",
"desc"
]
}
},
{
"term": {
"sex": 0
}
}
]
}
}
}
- 7.3 must_not:下面的两个条件,都不能满足,和 must 相反
{
"query": {
"bool": {
"must_not": [
{
"multi_match": {
"query": "沙僧",
"fields": [
"nickname",
"desc"
]
}
},
{
"term": {
"sex": 0
}
}
]
}
}
}
- 7.4 must、must_not、should 可以同时使用
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 771
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "大学"
}
}
],
"must_not": [
{
"term": {
"sex": "1"
}
}
],
"should": [
{
"range": {
"age": {
"gt": "18",
"lt": "22"
}
}
},
{
"match": {
"desc": "毕业"
}
}
]
}
}
}
8. DSL搜索-过滤器 post_filter
将金额money小于100并且大于1000的数据过滤掉
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 226
{
"query": {
"match": {
"desc": "大学"
}
},
"post_filter": {
"range": {
"money": {
"gt": 100,
"lt": 1000
}
}
}
}
post_filter 和 query 是同级的
9. DSL搜索-排序 sort
es默认是按 _score 排序
正序asc
倒序desc
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 144
{
"query": {
"match": {
"desc": "大学"
}
},
"sort": [
{
"age": "asc"
}
]
}
多个排序条件,组合排序
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 193
{
"query": {
"match": {
"desc": "大学"
}
},
"sort": [
{
"age": "asc"
},
{
"money": "desc"
}
]
}
text类型无法排序,keyword类型可以
10. DSL搜索-关键字高亮显示 highlight
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 157
{
"query": {
"match": {
"desc": "沙僧"
}
},
"highlight": {
"fields": {
"desc": {}
}
}
}
返回的数据中会对搜索关键字增加一个 em 标签
"highlight": {
"desc": [
"唐三藏是<em>沙僧</em>的师傅"
]
}
我们也可以自定义这个标签,使用 pre_tags 和 post_tags
POST /shop/_search HTTP/1.1
Host: 192.168.10.235:9200
Content-Type: application/json
Content-Length: 267
{
"query": {
"match": {
"desc": "沙僧"
}
},
"highlight": {
"pre_tags": [
"<span>"
],
"post_tags": [
"</span>"
],
"fields": {
"desc": {}
}
}
}
这样返回的数据中,em标签 则改成了 span
"highlight": {
"desc": [
"唐三藏是<span>沙僧</span>的师傅"
]
}
作者:_灯火阑珊处
链接:https://juejin.cn/post/6925707999247876110
来源:掘金
网友评论