数据准备
- 将ES中的索引全部删除
- 添加索引:
PUT hotel
- 添加几个文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| PUT /hotel { "mappings": { "properties": { "id":{ "type": "keyword" }, "name":{ "type": "keyword", "analyzer": "ik_max_word", "copy_to": "all" }, "address":{ "type": "keyword", "index": false }, "price":{ "type": "integer" }, "score":{ "type": "integer" }, "brand":{ "type": "keyword", "copy_to": "all" }, "city":{ "type": "keyword" }, "starName":{ "type": "keyword" }, "business":{ "type": "keyword", "copy_to": "all" }, "location":{ "type": "geo_point" }, "pic":{ "type": "keyword", "index": false }, "all":{ "type": "keyword", "analyzer": "ik_max_word" } } } }
GET /hotel/_search
|
可以注意到Hotel映射结构中:name
、brand
、business
三个字段分别使用了copy_to属性,它允许你将一个或多个字段的原始值复制到另一个指定的字段,优势在于:合并内容、简化查询、分析一致性
高级查询
全文检索查询
- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10
| # 全文检索查询 # match对用户输入的内容进行分词然后去倒排索引库检索 GET /hotel/_search { "query": { "match": { "name": "如家" } } }
|
使用合并内容字段all
进行查询,查询外滩如家将分词为 外滩、如家,即包含两个其中一个都命中结果
查询所有文档
- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6
| GET /hotel/_search { "query": { "match_all": {} } }
|
字段匹配查询:multi_match
查询的字段越多效率越慢
multi_match
与 match
类似,不同的是它可以在多个字段中查询。- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10
| # multi_match 多个字段搜索,参与查询字段越多,查询性能越差copy_to GET /hotel/_search { "query": { "multi_match": { "query": "外滩如家", "fields": ["brand","name","business"] } } }
|
单关键字精确查询:term
term
查询,精确的关键词匹配查询,不对查询条件进行分词,即只能单关键字精确查询。- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10 11 12
| #精确查询 一般查找KeyWord、数值、日期、Boolean # term GET /hotel/_search { "query": { "term": { "city": { "value": "深圳" } } } }
|
多关键字精确查询:terms
- terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysql 的 in
- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10 11 12
| GET /hotel/_search { "query": { "terms": { "name": [ "上海", "深圳" ] } } }
|
指定字段查询:_source
- 默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在
_source
的所有字段都返回。 - 如果我们只想获取其中的部分字段,我们可以添加
_source
的过滤 - 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| GET /hotel/_search { "_source": [ "name", "price", "address" ], "query": { "terms": { "name": [ "上海", "深圳" ] } } }
|
过滤字段:includes&excludes
- includes:来指定想要显示的字段
- excludes:来指定不想要显示的字段
- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| GET /hotel/_search { "_source": { "includes": [ "name", "price" ] }, "query": { "terms": { "name": [ "上海" ] } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| GET /hotel/_search { "_source": { "excludes": [ "name", "price" ] }, "query": { "terms": { "name": [ "上海" ] } } }
|
组合查询:bool
bool
把各种其它查询通过 must
(必须,类似 and)、must_not
(必须不,类似 not)、should
(应该 类似 or)的方式进行组合- 请求方式:GET 索引名/_search
- 请求体内容
查询名称必须包含如家,价格不能超过400,并且在我位置10km范围内的酒店,且结果按价格高到低排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| GET /hotel/_search { "query": { "bool": { "must": [ { "match": { "name": "如家" } } ], "must_not": [ { "range": { "price": { "gt": 400 } } } ], "filter": [ { "geo_distance": { "distance": "10km", "location": { "lat": 31.21, "lon": 121.5 } } } ] } }, "sort": [ { "price": "asc" } ] }
|
范围查询:range
range
查询找出那些落在指定区间内的数字或者时间。range
查询允许以下字符
查询价格1000-3000的酒店信息
1 2 3 4 5 6 7 8 9 10 11 12
| # range 范围查询 GET /hotel/_search { "query": { "range": { "price": { "gte": 1000, "lte": 3000 } } } }
|
模糊查询:fuzzy
fuzzy
:返回包含与搜索字词相似的字词的文档,更多fuzzy
有关解释请查看官方文档 (opens new window) -编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
更改字符(box → fox)
删除字符(black → lack)
插入字符(sic → sick)
转置两个相邻字符(act → cat)
为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。
通过 fuzziness
修改编辑距离。一般使用默认值 AUTO
,根据术语的长度生成编辑距离。
请求方式:GET 索引名/_search
1 2 3 4 5 6 7 8 9 10 11
| GET /hotel/_search { "query": { "fuzzy": { "all": { "value": "乡" } } } }
|
精确查询地理位置:geo_distance
1 2 3 4 5 6 7 8 9 10 11
| # 精确查询地理位置 GET /hotel/_search { "query": { "geo_distance":{ "distance":"2km", "location":"31.21,121.5" } } }
|
复合查询:function_score
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| # 复合查询 # function score 查询 GET /hotel/_search { "query": { "function_score": { "query": { "match": { "all": "外滩" } }, "functions": [ { "filter": { "term": { "brand": "如家" } }, "weight": 10 } ], "boost_mode": "sum" } } }
|
前缀查询:prefix
- 请求方式:GET 索引名/_search
- 请求体内容
1 2 3 4 5 6 7 8 9 10
| GET /hotel/_search { "query": { "prefix": { "name": { "value": "上" } } } }
|