ES Query DSL-复合查询和关联查询
ES 查询使用Query DSL定义查询条件,除了精确查询Term外还包括以下查询:符合查询、文本查询、关联查询等结构
复合查询Compound queries
复合查询是指可以组合其他复合查询或叶子查询。复合查询包括以下查询:
Bool 查询
匹配查询,返回分数只有0,1。 包括以下四种:
Msut: AND 查询,匹配文档分数为1
Filter: 过滤,匹配文档分数如果没有其他查询条件时为0
Must_not: 过滤, 非
Should: should列表中的条件是OR的关系, 可以通过minimum_should_match指定shuold最小匹配数量。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| POST _search { "query": { "bool" : { "must" : { "term" : { "user.id" : "kimchy" } }, "filter": { "term" : { "tags" : "production" } }, "must_not" : { "range" : { "age" : { "gte" : 10, "lte" : 20 } } }, "should" : [ { "term" : { "tags" : "env1" } }, { "term" : { "tags" : "deployed" } } ], "minimum_should_match" : 1, "boost" : 1.0 } } } |
Boosting query
对boosting 的 positive条件匹配的文档,如果满足negative条件,则对其分数进行较弱。通过boosting查询可以实现不排除特定文档,但减弱其分数。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "boosting": { "positive": { "term": { "text": "apple" } }, "negative": { "term": { "text": "pie tart fruit crumble tree" } }, "negative_boost": 0.5 } } } |
negative_boost: 指定分数削减值,设置在0-1之间。
Constant score query
封装一个filter查询, 通过boost参数指定查询匹配条件的分数。
|-----------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "constant_score": { "filter": { "term": { "user.id": "kimchy" } }, "boost": 1.2 } } } |
Disjunction max query
分离最大化查询,对多个查询条件返回的文档中,文档返回分数只返回查询匹配分数最大的分数, 比如一个查询关键字 A, 查询标题或内容中包含A的文档。 其中标题的匹配分数为1, 内容匹配分数也为0.5, 则多个文档,只要是标题中包含中都返回并且分数都是1.
为了在最大查询分数的前提下再考虑其他查询匹配, 比如标题中包含,并且内容中也包含的排名靠前,加入tie_breaker参数,将其他查询条件所得分数*tie_breaker,最后再加上最高分数为最终得分
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "dis_max": { "queries": [ { "term": { "title": "Quick pets" } }, { "term": { "body": "Quick pets" } } ], "tie_breaker": 0.7 } } } |
Function score query
定义一个query,和一个或多个函数,重新计算返回文档的分数。可以指定多个函数, 通过filter和匹配文档和函数
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "function_score": { "query": { "match_all": {} }, "boost": "5", "functions": [ { "filter": { "match": { "test": "bar" } }, "random_score": {}, "weight": 23 }, { "filter": { "match": { "test": "cat" } }, "weight": 42 } ], "max_boost": 42, "score_mode": "max", "boost_mode": "multiply", "min_score": 42 } } } |
score_mode: 定义文档如何对多个分数计算进行计算。包括以下合法值:Multiply,sum,avg,first(第一个匹配函数计算的值),max,min,
weight: 权重, 计算所得的分数*weight,权重将作用在平均分上。 如两个函数分别返回分数1,2, 权重为3,4 则平均分为(1*3+2*4)/(3+4)
max_boost: 最高分。
boost_mode:计算所得分数和查询所得分数的结合模式,包括:multiply,
replace, sum, avg, max, min。
min_score:最低分,过滤器, 低于该值的文档将被过滤掉。
计算函数:
Script_score:数字计算公式,可以使用文档数字字段。
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "function_score": { "query": { "match": { "message": "elasticsearch" } }, "script_score": { "script": { "source": "Math.log(2 + doc['my-int'].value)" } } } } } |
Weight:计算分数乘于指定的weight值。
"weight" : number
Random_score
返回0,1的随机数。[0,1)
|--------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "function_score": { "random_score": { "seed": 10, "field": "_seq_no" } } } } |
field_value_factor
使用文档域产生分数, 类似于脚本,但采用对域值的形式。
|--------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /_search { "query": { "function_score": { "field_value_factor": { "field": "my-int", "factor": 1.2, "modifier": "sqrt", "missing": 1 } } } } |
Field: 起作用的文档域
Factor:值的乘数
Modifier: 作用在域上的方法。none, log, log1p, log2p, ln, ln1p, ln2p, square, sqrt, or reciprocal. 默认 none.
另外还有Decay functions(衰减函数)详见官方文档。
Function score query | Elasticsearch Guide [7.17] | Elastic
关联查询
Nested查询
Nested查询需要文档域的类型为nested类型。Nested查询需要注意 如果内嵌对象是个列表,则返回只要其中一个内嵌对象符合内嵌对象查询的文档。(内嵌查询作用在内嵌对象上,返回文档。 而文档查询作用在文档上。)
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| PUT my-index { "mappings": { "properties": { "comments": { "type": "nested" } } } } PUT my-index/_doc/1?refresh { "comments": [ { "author": "kimchy" } ] } PUT my-index/_doc/2?refresh { "comments": [ { "author": "kimchy" }, { "author": "nik9000" } ] } PUT my-index/_doc/3?refresh { "comments": [ { "author": "nik9000" } ] } POST my-index/_search { "query": { "nested": { "path": "comments", "query": { "bool": { "must_not": [ { "term": { "comments.author": "nik9000" } } ] } } } } } | { ... "hits" : { ... "hits" : [ { "_index" : "my-index", "_type": "_doc", "_id" : "1", "_score" : 0.0, "_source" : { "comments" : [ { "author" : "kimchy" } ] } }, { "_index" : "my-index", "_type": "_doc", "_id" : "2", "_score" : 0.0, "_source" : { "comments" : [ { "author" : "kimchy" }, { "author" : "nik9000" } ] } } ] } } |
Has child query
关联查询,作用于join类型的文档域, Has child查询将返回满足查询的子文档对应的父文档。Has_child查询比起其他查询速度明显慢。
|------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| PUT /my-index-000001 { "mappings": { "properties": { "my-join-field": { "type": "join", "relations": { "parent": "child" } } } } } | GET /_search { "query": { "has_child": { "type": "child", "query": { "match_all": {} }, "max_children": 10, "min_children": 2, "score_mode": "min" } } } |
Has parent query
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /my-index-000001/_search { "query": { "has_parent": { "parent_type": "parent", "query": { "term": { "tag": { "value": "Elasticsearch" } } } } } } |
Parent id query
|------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
| PUT /my-index-000001 { "mappings": { "properties": { "my-join-field": { "type": "join", "relations": { "my-parent": "my-child" } } } } } | PUT /my-index-000001/_doc/1?refresh { "text": "This is a parent document.", "my-join-field": "my-parent" } |
| PUT /my-index-000001/_doc/2?routing=1&refresh { "text": "This is a child document.", "my-join-field": { "name": "my-child", "parent": "1" } } | GET /my-index-000001/_search { "query": { "parent_id": { "type": "my-child", "id": "1" } } } |
Match All /Match none
匹配全部或none。
|-----------------------------------------------|------------------------------------------------|
| GET /_search { "query": { "match_all": {} } } | GET /_search { "query": { "match_none": {} } } |