大数据利器Elasticsearch之dis_max查询
本Elasticsearch相关文章的版本为:7.4.2
图书馆收藏了一些书籍,相关信息存储在book索引内,下面是两个文档信息:
POST /book/_doc/1
"body": "elasticsearch filter",
"title": "elasticsearch basic query"
POST /book/_doc/2
"body": "single value search",
"title": "elasticsearch aggs query"
}
小明同学想查询elasticsearch聚合查询方面相关的知识: 如果使用should对body和title进行match查询:
POST /book/_search
"query": {
"bool": {
"should": [
{"match": {"body": "elasticsearch aggs"}},
{"match": {"title": "elasticsearch aggs"}}
}
你会觉得文档2会更符合小明的需要,但是返回的查询结果的相关性得分缺失文档1高于文档2:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
"max_score" : 0.9372343,
"hits" : [
"_index" : "book",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.9372343,
"_source" : {
"body" : "elasticsearch filter",
"title" : "elasticsearch basic query"
"_index" : "book",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.87546873,
"_source" : {
"body" : "single value search",
"title" : "elasticsearch aggs query"
}
那是因为should查询的相关性得分计算过程是:
1. 使用match查询"elasticsearch aggs"时,首先会被拆分为elasticsearch和aggs两个分词;
2. 然后使用should里面的每个子句去查询同一个文档:
3. 文档1的body和title都命中elasticsearch,满足should中的两个子句,文档得2分;
4. 文档2的title命中elasticsearch和aggs,但是只满足了should中关于title的子句,文档得1分, 5. 所以最后文档1的得分高于文档2,尽管文档2的匹配度更高。
那么,如何才能让匹配度更高的文档2的相关性得分高于文档1呢? 那么需要使用dis_max查询了。
dis_max查询的得分计算:
以最佳匹配的子句的得分作为整个文档的相关性得分。
POST /book/_search?size=1000
"query": {
"dis_max": {
"tie_breaker": 0.3,
"queries": [
{"match": {"body": "elasticsearch aggs"}},
{"match": {"title": "elasticsearch aggs"}}
}
那么,dis_max查询过程中文档1和文档2的得分计算过程为:
1. 使用match查询"elasticsearch aggs"时,首先会被拆分为elasticsearch和aggs两个分词;
2. 然后使用should里面的每个子句去查询同一个文档:
3. 文档1的body和title都命中elasticsearch,body子句得1分,title子句也是1分,最后取两个子句中的最高分作为文档1的最后得分,即最后文档1的相关性得分为1分;
4. 文档2的title命中elasticsearch和aggs,body没有命中任何分词,所以title子句得分为2分,body子句得分为0分,最后去body和title子句的最高分作为文档2的最后的得分,即文档2得2分; 5. 所以最后文档2的得分高于文档1,符合我们的需求。
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
"max_score" : 0.87546873,
"hits" : [
"_index" : "book",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.87546873,
"_source" : {
"body" : "single value search",
"title" : "elasticsearch aggs query"
"_index" : "book",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.80960923,
"_source" : {
"body" : "elasticsearch filter",