elk笔记13--Queries-term-level queries

1 term-level 查询简介

基于结构化数据中准确的值,用户可以使用term级别的查询来搜索文档。常见结构化数据包括日期范围、IP地址、价格、产品IDs等。

与全文检索不同,项级别的查询不分析查找的项,它会匹配存储在某个字段中的具体项。当查询的项为keyword字段时,它将使用 normalizer 属性来正则化搜索的项。

该范畴内的查询包括 exists查询、fuzzy查询、ids查询、prefix查询、range查询、regexp查询、term查询、terms查询、terms_set查询、type查询、wildcard查询 等11类。

2 term-level 查询类型

2.1 exists query

该查询返回包含一个值的文档,且该值不能为null 或 [].

获取包含字段cc的文档
GET test/_search
{
"query": {
"exists": {
"field": "cc"
}
}
}
可以通过must_not 获取cc字段不存在的文档
GET test/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "cc"
}
}
]
}
}
}

2.2 fuzzy query

返回包含和搜索项相似项的文档,该相似性是由 ​​Levenshtein edit distance​​​ 来评估的。
编辑距离指的是从一个项变为另外一个项所需要的单字符改变的数量,这些改变可以包括:
改变一个字符(box → fox)
去掉一个字符 (black → lack)
插入一个字符 (sic → sick)
调换2个相连字符的位置 (act → cat)

kibana_sample_data_ecommerce 中有Mary用户,根据上述改变可知:mery,ary,marys,mray都是mary的相似项。
GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"query": {
"fuzzy": {
"user": {
"value": "mery"
}
}
},
"size": 1
}

2.3 ids query

基于文档的id来返回文档,该IDs存放在 _id 字段中。
该方式比较适合查找自定义 _id 字段的文档。

GET test/_search
{
"query": {
"ids": {
"values": ["1","3"]
}
}
}

2.4 prefix query

根据字段指定的前缀来查找文档。
prefix 的 顶层参数为field,即指定field;
field 的 顶层参数为value,即为前缀字符或者字符串。

正常情况下prefix 查询效率不高,可以在mapping中添加 index_prefixes 属性来提高搜索速度。如果设置为enabled,则指定的字段会多出2-5个字符的前缀,这让es执行前缀查询更加快,但是占用更多的存储空间。

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"query": {
"prefix": {
"user": {
"value": "ma"
}
}
},
"size": 1
}

2.5 range query

根据指定字段的范围来查找文档。
比较方式又:gt(大于),lt(小于),gte(大于等于),lte(小于等于)

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"size": 0,
"query": {
"range": {
"taxful_total_price": {
"gt": 100,
"lt": 200
}
}
}
}

2.6 regexp query

根据指定字段,找到符合特定正则表达的文档。
顶层参数 为filed,field子参数包括value,flags,max_determinized_states,rewrite;
其中value为正则内容;
flags表示可以使用的正则表达操作符,默认ALL为全部可用,​​​regexp-optional-operators​​​;
max_determinized_states 表示为自动机状态的么最大数量,默认值为10000;
rewrite 决定来相关度分数计算方式,Lucene 如何将原始query转化为bool query或者bit set;

GET kibana_sample_data_ecommerce/_search
{
"query": {
"regexp": {
"user": {
"value": "el.*a",
"flags" : "ALL",
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}

2.7 term query

根据某个字段,返回字段值和指定值相同的文档;
顶层参数 为filed,field子参数包括value,boost;
其中,boost值默认为1.0;

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"size": 1,
"query": {
"term": {
"user": {
"value": "mary"
}
}
}
}
"user": {"value": "mary"} 也可以调整为 "user": "mary",但是调整后无法使用boost参数;
注意:term不适合对text类型搜索,通常不会搜索到想要的结果,如果使用全文搜索则应该使用match来查找;

2.8 terms query

根据某个字段,只要和指定的某个值相同即可返回文档;
顶层参数 field 和 boost;
field 中为目标值数组,es中限制数组最大值为 65536;

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"size": 1,
"query": {
"terms": {
"user":[ "mary","abd"]
}
}
}

2.9 terms_set query

根据某个字段,返回文档中必须包括最少数量的特定值;我们可以通过一个字段或者script来定义最小匹配数量。
顶层参数field,子参数为terms(必选项),minimum_should_match_field,minimum_should_match_script。

PUT /job-candidates
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"programming_languages": {
"type": "keyword"
},
"required_matches": {
"type": "long"
}
}
}
}
PUT /job-candidates/_doc/1?refresh
{
"name": "Jane Smith",
"programming_languages": ["c++", "java"],
"required_matches": 2
}
PUT /job-candidates/_doc/2?refresh
{
"name": "Jason Response",
"programming_languages": ["java", "php"],
"required_matches": 2
}
GET /job-candidates/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": ["c++", "java", "php"],
"minimum_should_match_field": "required_matches"
}
}
}
}
minimum_should_match_field 对应的值必须为指定的字段,不能为随机定义的数值;
也可以使用script的方式:
GET /job-candidates/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": ["c++", "java", "php"],
"minimum_should_match_script": {
"source": "Math.min(params.num_terms, doc['required_matches'].value)"
},
"boost": 1.0
}
}
}
}

2.10 type query

该查询返回指定type类型的文档。
es7.0 之后废弃了type类型,一个index只能有一个type类型,因此这类查询后续意义不太大。

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"query": {
"type": {
"value": "_doc"
}
}
}

2.11 wildcard query

Returns documents that contain terms matching a wildcard pattern.
根据某个字段,返回包括特定通配符的文档。当前通配符只支持 ? 和 * 2种。
顶层参数field,子参数value,boost,rewrite。

GET kibana_sample_data_ecommerce/_search
{
"track_total_hits": true,
"query": {
"wildcard": {
"user": {
"value": "mar?*",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}

3 说明

  1. 参考文档
    ​​​term-level-queries​​​ 更多DSL 查询内容见​​elk笔记13–Query DSL​
  2. 测试环境
    本文测试案例对应的 es 版本为7.2.1
    测试数据为kibana自带数据,Home->Add data->Sample data->Sample eCommerce orders