一、DSL查询文档
本章目标
- 文本检索:match_all、match、multi_match
- 精确查询:term、range
- 地理坐标查询:geo_distance
- 复合查询:function_score、bool
1. 说明
查询语法:
GET /索引库名/_search { "query": {}, #放查询条件 "sort": [], #放排序条件 "from": 起始索引, #放分页的起始索引 "size": 查询数量, #放分页的查询几条 "highlight": {}, #放高亮字段 "aggs": {}, #放聚合分组条件 "suggest": {} #放搜索提示条件 }
1.1 查询功能分类
Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:
查询所有:查询出所有数据,一般测试用。例如:match_all
全文本检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
match
multi_match
精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
range
term
地理(geo)查询:根据经纬度查询。例如:
geo_distance
geo_bounding_box
复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:
bool
function_score
1.2 查询语法说明
查询的语法基本一致:
GET /索引名称/_search { "query": { "查询类型": { "查询条件": "条件值" } } }
我们以查询所有为例,其中:
查询类型为match_all
没有查询条件
# 查询所有 GET /索引名称/_search { "query": { "match_all": { } } }
其它查询无非就是查询类型、查询条件的变化
2. 文本检索
全文检索查询的基本流程如下:
对用户搜索的内容做分词,得到词条
根据词条去倒排索引库中匹配,得到文档id
根据文档id找到文档,返回给用户
比较常用的场景包括:
商城的输入框搜索
百度输入框搜索
例如京东:
因为是拿着词条去匹配,因此参与搜索的字段也必须是可分词的text类型的字段。语法
常见的全文检索查询包括:
match查询:单字段查询
multi_match查询:多字段查询,任意一个字段符合条件就算符合查询条件。注意:字段越多,性能越差
match
match查询语法如下:
GET /索引名称/_search { "query": { "match": { "字段": "搜索值" } } }
mulit_match
mulit_match语法如下:
GET /索引名称/_search { "query": { "multi_match": { "query": "搜索值", "fields": ["字段1", "字段2", ...] } } }
示例
#match 单字段检索 GET /hotel/_search { "query": { "match": { "all": "北京如家" } } } #multi_match多字段检查 GET /hotel/_search { "query": { "multi_match": { "query": "北京如家", "fields": ["name", "brand", "business"] } } }
注意
多字段检索的性能问题:使用多字段检索时,字段越多,检索的性能越差
解决方案:使用
copy_to
,把多个字段值拷贝到一个字段里,对这个字段用match
检索,可以达到同样效果,而且效率更高
3. 精确查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:
term:根据词条精确值查询
因为精确查询是不分词的,所有查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。
range:根据值的范围查询
范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。
语法
term查询
# term查询 GET /indexName/_search { "query": { "term": { "字段": { "value": "值" } } } }
range查询
# range查询 GET /indexName/_search { "query": { "range": { "字段": { "gte": 10, # 这里的gte代表大于等于,gt则代表大于 "lte": 20 # lte代表小于等于,lt则代表小于 } } } }
示例
# 1. term词条匹配。不分词,必须精确匹配。 查询“如家”品牌的酒店 GET /hotel/_search { "query": { "term": { "brand": { "value": "如家" } } } } # 2. range范围匹配。查询price价格在300~500之间的酒店 GET /hotel/_search { "query": { "range": { "price": { "gte": 300, "lte": 500 } } } }
4. 地理坐标查询
所谓的地理坐标查询,其实就是根据经纬度查询,官方文档:Geo queries | Elasticsearch Guide [8.7] | Elastic
常见的使用场景包括:
携程:搜索我附近的酒店
滴滴:搜索我附近的出租车
微信:搜索我附近的人
附近的酒店:
附近的车:
语法
矩形范围查询【了解】
矩形范围查询,也就是
geo_bounding_