ElasticSearch-4-高级查询Query DSL
1、简介
2、语法介绍
GET /<index_name>/_search {json请求体数据}
查看指定字段、分页、排序、范围查询
GET /<your-index-name>/_search { "query": { // 匹配所有文档 "match_all": {}, // 返回前10条数据 "size": 10, // 返回指定字段 "_source": ["field1","field2"], // 只看以obj.开头的字段 "_source": "obj.*", // - from&size分页查询 "from": 0, "size": 5, // 根据指定字段排序 "sort": [ { "age": "desc" } ], // 范围查询 "range": { "<field_name>": { "gte": <lower_bound>, // 表示大于或等于 "lte": <upper_bound>, // 表示小于或等于 "gt": <greater_than_bound>, // 表示严格大于 "lt": <less_than_bound> // 表示严格小于 }, // 根据一组id查询 "ids": { "values": ["id1", "id2", "id3", ...], } } }
2、精确匹配
GET /{index_name}/_search
{
"query": {
"term": {
"{field.keyword}": {
"value": "your_exact_value"
}
}
}
}
GET /employee/_search { "query": { "constant_score": { "filter": { "term": { "address.keyword": "广州白云山公园" } } } } }
terms多值精准匹配:
GET /<index_name>/_search { "query": { "terms": { "<field_name>": [ "value1", "value2", "value3", ... ] } } }
- now:当前时间点。
- now-1d:从当前时间点向前推1天的时间点。
- now-1w:从当前时间点向前推1周的时间点。
- now-1M:从当前时间点向前推1个月的时间点。
- now-1y:从当前时间点向前推1年的时间点。
- now+1h:从当前时间点向后推1小时的时间点。
# 返回所有在当前时间点前两年内的产品文档。 GET /product/_search { "query": { "range": { "date": { "gte": "now-2y" } } } }
3、exists——是否存在查询
exists查询用于查找包含特定字段的文档,无论该字段的值是什么(包括null值,但注意null值在Elelasticsearch中不会被索引,所以实际上exists查询是查找那些字段存在且索引了的文档)。
查询某个字段存在的文档
GET /your_index/_search { "query": { "exists": { "field": "field_name" } } }
反向查询:查找某个字段不存在的文档
must_not与exists结合来查找字段不存在的文档。GET /products/_search { "query": { "bool": { "must_not": { "exists": { "field": "description" } } } } }
4、prefix——前缀匹配
-
如果字段是text类型,那么它会被分词,而prefix查询是针对分词后的术语进行前缀匹配。例如,如果文档的title字段被分词为["apple", "iphone"],那么前缀"app"可以匹配到"apple",但前缀"apple i"可能无法匹配,因为"apple i"不是任何一个术语的前缀(它是两个术语的组合)。
-
如果字段是keyword类型,那么整个字段作为一个术语,前缀匹配是针对整个字段值的。
GET /<index_name>/_search { "query": { "prefix": { "your_field_name": { "value": "your_prefix_string" } } } }
5、wildcard——通配符匹配
- 星号(*):表示零或多个字符,可用于匹配任意长度的字符串。
- 问号(?):表示一个字符,用于匹配任意单个字符。
基本语法:
GET /<index_name>/_search { "query": { "wildcard": { "your_field_name": { "value": "your_search_pattern" } } } }
示例:
GET /employee/_search { "query": { "wildcard": { "address.keyword": { "value": "*州*公园" } } } }
6、regexp——正则匹配查询
基本语法:
GET /<index_name>/_search { "query": { "regexp": { "your_field_name": { "value": "your_search_pattern" } } } }
7、fuzzy——支持编辑距离的模糊查询
基本语法如下:
GET /<index_name>/_search { "query": { "fuzzy": { "your_field": { "value": "search_term", "fuzziness": "AUTO", "prefix_length": 1 } } } }
- fuzziness参数用于编辑距离的设置,其默认值为AUTO,支持的数值为[0,1,2]。如果值设置越界会报错。
- prefix_length: 搜索词的前缀长度,在此长度内不会应用模糊匹配。默认是0,即整个词都会被模糊匹配。
8、terms_ set——用于解决多值字段中的文档匹配问题
terms set 查询是 Elasticsearch 中一个特殊的查询,它允许根据匹配的项数来筛选文档。特别的是,这个匹配的项数可以是一个变量,该变量存储在文档的另一个字段中。
基本语法:
GET /your_index/_search { "query": { "terms_set": { "field_name": { "terms": ["term1", "term2", "term3"], "minimum_should_match": 2 // 最小匹配数, "minimum_should_match_field": "required_matches" // 从指定的字段获取最小匹配数 } } } }
minimum_should_match_script: 提供一个自定义脚本,用于动态计算匹配数量。如果需要动态设置匹配所需的术语数,这个参数将非常有用。
示例:
GET /candidates/_search { "query": { "terms_set": { "skills": { "terms": ["Java", "Python", "Elasticsearch"], "minimum_should_match_script": { "source": """ // 使用缓存参数,避免重复计算 if (params.cached_threshold == null) { // 复杂的计算逻辑 params.cached_threshold = Math.min(3, doc['skills'].size()); } return params.cached_threshold; """, "params": { "cached_threshold": null } } } } } }
3、全文检索
- 精确不对待检索文本进行分词处理,而是将整个文本视为一个完整的词条进行匹配。
- 全文检索则需要对文本进行分词处理。在分词后,每个词条将单独进行检索,并通过布尔逻辑(如与、或、非等)进行组合检索,以找到最相关的结果。
1、match——分词查询
基本语法:
GET /<index_name>/_search { "query": { "match": { "<field_name>": "<query_string>" } } }
# 最少匹配广州,公园两个词 GET /employee/_search { "query": { "match": { "address": { "query": "广州公园", "minimum_should_match": 2 } } } }
2、multi_match——多字段查询
GET /<index_name>/_search { "query": { "multi_match": { "query": "<query_string>", "fields": ["<field1>", "<field2>", ...] } } }
3、match_phrase短语查询
GET /<index_name>/_search { "query": { "match_phrase": { "<field_name>": { "query": "<phrase>" } } } }
4、query_string——支持与或非表达式的查询
- 与(AND)、或(OR)和非(NOT)(必须大写)。
- 以及通配符(
?匹配任意单个字符;*匹配零个或多个字符。) - 模糊搜索(使用
~进行模糊匹配,后面可以跟一个编辑距离(默认为2))。 - 正则表达式。使用
/包裹正则表达式。示例:title:/elastik.*/
通过使用括号将条件分组,以控制逻辑运算的优先级。如果查询字符串中包含特殊字符(如+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /),需要使用反斜杠\进行转义。
范围查询
数值和日期字段可以使用范围查询:
age:[18 TO 30]包含边界
age:{18 TO 30}不包含边界
age:[18 TO *]大于等于18
age:{* TO 30}小于30
也可以使用比较操作符:
-
age:>=18 -
age:<30 -
age:(>=18 AND <30)
基础语法:
GET /<index_name>/_search { "query": { "query_string": { "query": "<your_query_string>", "default_field": "<field_name>" } } }
示例:
GET /employee/_search { "query": { "query_string": { "fields": ["name","address"], "query": "张三 OR (广州 AND 王五)" } } }
5、simple_query_string
- + 替代AND
- | 替代OR
- - 替代NOT
在生产环境中推荐使用 simple_query_string 而不是 query_string 。主要是因为simple_query_string 提供了更宽松的语法,能够容忍一定程度的输入错误,而不会导致整个
查询失败。如果直接将用户输入用于query_string查询,可能会受到注入攻击,建议使用simple_query_string或者对用户输入进行转义。
基础语法:
GET /<index_name>/_search { "query": { "simple_query_string": { "query": "<query_string>", "fields": ["<field1>", "<field2>", ...], "default_operator": "OR" // 或 "AND" } } }
4、bool query布尔查询
- 搜索上下文(query context):使用搜索上下文时,Elasticsearch需要计算每个文档与搜索条件的相关度得分,这个得分的计算需使用一套复杂的计算公式,有一定的性能开销,带文本分析的全文检索的查询语句很适合放在搜索上下文中。
- 过滤上下文(filter context):使用过滤上下文时,Elasticsearch只需要判断搜索条件跟文档数据是否匹配,例如使用Term query判断一个值是否跟搜索内容一致,使用Range query判断某数据是否位于某个区间等。过滤上下文的查询不需要进行相关度得分计算,还可以使用缓存加快响应速度,很多术语级查询语句都适合放在过滤上下文中。

示例:使用搜索上下文
GET /books/_search { "query": { "bool": { "must": [ { "match": { "title": "java编程" } },{ "match": { "description": "性能优化" } } ] } } }
示例:使用过滤上下文:
GET /books/_search { "query": { "bool": { "filter": [ { "term": { "language": "java" } }, { "range": { "publish_time": { "gte": "2010-08-01" } } } ] } } }
5、highlight高亮
- pre_tags 前缀标签
- post_tags 后缀标签
- tags_schema 设置为styled可以使用内置高亮样式
- require_field_match 多字段高亮需要设置为false
示例:
GET /products/_search { "query": { "term": { "name": { "value": "牛仔" } } }, "highlight": { "fields": { "*":{} } } }
GET /products/_search { "query": { "multi_match": { "fields": ["name","desc"], "query": "牛仔" } }, "highlight": { "post_tags": ["</span>"], "pre_tags": ["<span style='color:red'>"], "fields": { "*":{} // 多字段高亮 // "name": {}, "desc": {} } } }
6、地理空间位置查询
PUT /my_index { "mappings": { "properties": { "location": { "type": "geo_point" } } } } // 使用以下查询来找到距离给定坐标点(例如lat和lon)小于或等于10公里的所有文档 GET /my_index/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_distance": { "distance": "10km", "distance_type": "arc", "location": { "lat": 39.9, "lon": 116.4 } } } } } }
- "geo_distance" 是一个地理距离查询,它允许您指定一个距离和一个点的坐标。
- "distance" 是查询的最大距离,单位可以是米(m)、公里(km)等。
- "distance_type" 可以是 arc(以地球表面的弧长为单位)或 plane(以直线距离为单位)。通常对于地球上的距离查询,建议使用 arc。
- "location" 是查询的参考点,包含纬度和经度坐标。

浙公网安备 33010602011771号