0%

Query & Filtering 与多字符串多字段查询

1. Query 和 filter Context

相关阅读:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-filter-context.html

在 ElasticSearch 中,有 Query 和 Filter 两种不同的 Context,其中 Query Context 会进行相关性算分,而 Filter Context 则不需要进行算分,其可以利用 Cache 一次获得更好的性能。

例如在 bool query 中的 must_not 和 filter 即为 Filter Context,而一般的查询都会进行相关性算分,即为 Query Context ,其会计算出 _score 的值。

例如 Filter Context 不影响相关性得分,其检索出来的 _score 值为 0,而 Query Context 检索出来的 _score 的值为实际计算出来的值:

Filter Context Query Context

2. Bool Query

相关阅读:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl-bool-query.html

假设现在要搜索一本电影,需要包含以下一些条件:

  • 评论中包含了 Guitar,用户打分高于 3 分,同时上映日期要在 1993 与 2000 年之间

要实现这样的查询可以采用 bool query 进行实现。一个 bool query,是一个或者多个查询子句的组合,其总共包括 4 种子句,其中两种会影响算分,两种不影响算分。

相关性不只是全文本检索的专利,也适用于 yes or no 的子句,匹配的子句越多,相关性评分越高。如果多条查询子句被合并为一条复合查询语句,比如 bool query,则每个查询子句计算得出的评分会被合并到总的相关性评分中。

bool query 子句

假设现在要查询 price 为 30,且同时不能小于等于 10 和 productID 需要是 JODL-X-1937-#pV7 或者 XHDK-A-1293-#fJ3 的有效产品,其 DSL 如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
POST /products/_search
{
"query": {
"bool" : {
"must" : {
"term" : { "price" : 30 }
},
"filter": {
"term" : { "avaliable" : true }
},
"must_not" : {
"range" : {
"price" : { "lte" : 10 }
}
},
"should" : [
{ "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
{ "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
],
"minimum_should_match": 1
}
}
}

需要额外说明的是 minimum_should_match 参数用于设置返回的文档必须匹配的最少 should 分支数。不设置时则默认值为 0,在存在 must 子句时则不强制匹配 should 中的查询条件。

子查询可以任意顺序出现在 bool query 语句中,同时可以嵌套多个 bool query。同 should 一样,must、filter 和 must_not 都可以是数组格式以此来组合更多的查询条件。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
POST /products/_search
{
"query": {
"bool" : {
"must" : [
{
"bool": {
"must": [
{"term" : { "price" : 30 }}
]
}
},
{
"term" : { "avaliable" : true }
}
],
"must_not" : {
"range" : {
"price" : { "lte" : 10 }
}
},
"should" : [
{ "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
{ "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
],
"minimum_should_match": 1
}
}
}

3. Boosting Query

相关阅读:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl-boosting-query.html

boosting 是控制相关度的一种手段,可以通过参数 boost 进行设置。当 boost 大于 1 时,打分的相关度相对性提升,大于 0 且小于 1 时,打分的权重会相对性降低,而小于 0 时则会贡献负分。

比如现在需要将 news 索引中内容包含 apple 的相关性得分更高,而包含 pie 的相关性得分打低,可以通过如下语句查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
POST news/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"content": "apple"
}
},
"negative": {
"match": {
"content": "pie"
}
},
"negative_boost": 0.5 // 负相关匹配条件 boost 权重设置偏低,相关性会降低
}
}
}
// 响应
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.16786805,
"hits" : [
{
"_index" : "news",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple Mac"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple iPad"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.08640266,
"_source" : {
"content" : "Apple employee like Apple Pie and Apple Juice"
}
}
]
}
}

可以观察到 content 中包含 pie 的记录得分更低,更加靠后显示。

------ 本文结束------