Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query)

2023-06-15,,

Query DSL (Domain Specific Language),基于json的查询方式

1、Constant score query,常量分值查询,目的就是返回指定的score,一般都结合filter使用,因为filter context忽略score。

GET /customer/_search
{
"query": {
"constant_score": {
"filter": {
"match": {
"addr": "天津,北京"
}
},
"boost": 5.2
}
}
} result:返回结果中score都是被指定的5.2
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 5.2,
"hits" : [
{
"_index" : "customer",
"_type" : "doc",
"_id" : "510221197801023611",
"_score" : 5.2,
"_source" : {
"name" : "王刚",
"id" : "510221197801023611",
"addr" : "北京市朝阳区未名路109号",
"tel" : "13901004491"
}
},
{
"_index" : "customer",
"_type" : "doc",
"_id" : "51228199001013611",
"_score" : 5.2,
"_source" : {
"name" : "白开心",
"id" : "51228199001013611",
"addr" : "天津市海港路1021号",
"tel" : "13590850990"
}
}
]
}
}

2、bool query,布尔查询

Bool查询对应Lucene中的BooleanQuery,它由一个或者多个子句组成,每个子句都有特定的类型。

must  返回的文档必须满足must子句的条件,并且参与计算分值
filter  返回的文档必须满足filter子句的条件。但是不会像must一样参与计算分值
should 返回的文档可能满足should子句的条件。bool查询在query context中,并且有一个must或filter子句,即使没有一个should查询匹配,文档也会进行bool匹配。在这种情况下,这些should仅用于影响分数。如果在filter context中,或者没有must或filter子句,那么should子句必须和文档匹配,才能匹配bool查询。这种行为由minimum_should_match 参与决定。
must_not 返回的文档必须不满足must_not定义的条件。

官网的例子:

POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user" : "kimchy" }
},
"filter": {
"term" : { "tag" : "tech" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tag" : "wow" } },
{ "term" : { "tag" : "elasticsearch" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}

bool查询案例分解:

第一步:查询name为“李云龙”的文档

GET /customer/_search
{
"query": {
"bool": {
"must": {
"term":{"name.keyword":"李云龙"}
}
}
}
}
返回三个文档:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.4916549,
"hits" : [
{
"_index" : "customer",
"_type" : "doc",
"_id" : "4",
"_score" : 1.4916549,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "昆明市滇池路阳光时代1栋1单元",
"tel" : "13808712808"
}
},
{
"_index" : "customer",
"_type" : "doc",
"_id" : "224",
"_score" : 1.4916549,
"_source" : {
"name" : "李云龙",
"id" : "224",
"addr" : "天津市阳光路2008号",
"tel" : "13908712808"
}
},
{
"_index" : "customer",
"_type" : "doc",
"_id" : "510221197001013611",
"_score" : 1.4916549,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "上海市浦东区华北路8号",
"tel" : "13908712808"
}
}
]
}
}

第二步:加入过滤条件,只保留id为510221197001013611的文档

GET /customer/_search
{
"query": {
"bool": {
"must": {
"term":{"name.keyword":"李云龙"}
},
"filter": {
"term": {
"id": "510221197001013611"
}
}
}
}
} 返回结果减少到2个文档,并且score相同:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.4916549,
"hits" : [
{
"_index" : "customer",
"_type" : "doc",
"_id" : "4",
"_score" : 1.4916549,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "昆明市滇池路阳光时代1栋1单元",
"tel" : "13808712808"
}
},
{
"_index" : "customer",
"_type" : "doc",
"_id" : "510221197001013611",
"_score" : 1.4916549,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "上海市浦东区华北路8号",
"tel" : "13908712808"
}
}
]
}
}

第三步:使用should,判断addr中必须有昆明市,这种情况下should子句会影响计分

GET /customer/_search
{
"query": {
"bool": {
"must": {
"term":{"name.keyword":"李云龙"}
},
"filter": {
"term": {
"id": "510221197001013611"
}
},
"should": [
{"match": {
"addr": "昆明市"
}}
]
}
}
}
返回结果中,地址是昆明市的文档score加重
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 3.408528,
"hits" : [
{
"_index" : "customer",
"_type" : "doc",
"_id" : "4",
"_score" : 3.408528,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "昆明市滇池路阳光时代1栋1单元",
"tel" : "13808712808"
}
},
{
"_index" : "customer",
"_type" : "doc",
"_id" : "510221197001013611",
"_score" : 1.5720221,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "上海市浦东区华北路8号",
"tel" : "13908712808"
}
}
]
}
}

第四步:加入must_not排除上海

GET /customer/_search
{
"query": {
"bool": {
"must": {
"term":{"name.keyword":"李云龙"}
},
"filter": {
"term": {
"id": "510221197001013611"
}
},
"should": [
{"match": {
"addr": "昆明市"
}}
],
"must_not": [
{"match": {
"addr": "上海"
}}
]
}
}
} 只返回一个文档:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 3.408528,
"hits" : [
{
"_index" : "customer",
"_type" : "doc",
"_id" : "4",
"_score" : 3.408528,
"_source" : {
"name" : "李云龙",
"id" : "510221197001013611",
"addr" : "昆明市滇池路阳光时代1栋1单元",
"tel" : "13808712808"
}
}
]
}
}

Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query)的相关教程结束。

《Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query).doc》

下载本文的Word格式文档,以方便收藏与打印。