Elasticsearch:按标签总重量进行搜索/排序

Rom*_*mko 5 elasticsearch

我必须解决一个超出我的Elasticsearch基本技能的问题。

我有一组对象-每个对象都有一组标签。喜欢:

obj_1 = ["a", "b", "c"]
obj_2 = ["a", "b"]
obj_3 = ["c", "b"]
Run Code Online (Sandbox Code Playgroud)

我想使用加权标签搜索对象。例如:

search_tags = {'a': 1.0, 'c': 1.5}
Run Code Online (Sandbox Code Playgroud)

我希望搜索标签为OR查询。那就是-我不想排除没有所有查询标签的文档。但我希望按重量最大的标签(它们是:每个匹配的标签乘以其重量)排序。

使用上面的示例,返回的文档顺序为:

  • obj_1(得分:1.0 + 1.5)
  • obj_3(分数:1.5)
  • obj_2(得分:1.0)

关于文档的结构和查询ES的正确方法,什么是最好的方法?

这里有一个类似的问题:弹性搜索-仅标记强度(嵌套/子文档增强),我不想在索引时指定权重-我希望在搜索时完成权重。

我当前的设置如下。

对象:

[
   "title":"1", "tags" : ["a", "b", "c"],
   "title":"2", "tags" : ["a", "b"],
   "title":"3", "tags" : ["c", "b"],
   "title":"4", "tags" : ["b"]
]
Run Code Online (Sandbox Code Playgroud)

而我的查询:

{ 
    "query": {
        "custom_filters_score": {
            "query": { 
                "terms": {
                    "tags": ["a", "c"],
                    "minimum_match": 1
                }
            },
            "filters": [
                {"filter":{"term":{"tags":"a"}}, "boost":1.0},    
                {"filter":{"term":{"tags":"c"}}, "boost":1.5}    
            ],
            "score_mode": "total"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于它只返回对象1和3。它也应该与对象2相匹配(具有标签“ a”),还是我做错了什么?

建议更新

好。将boost更改为script以计算最小值。删除了最小匹配项。我的请求:

{
    "query": {
        "custom_filters_score": {
            "query": {
                "terms": {
                    "tags": ["a", "c"]
                }
            },
            "filters": [
                {"filter":{"term":{"tags":"a"}}, "script":"1.0"},
                {"filter":{"term":{"tags":"c"}}, "script":"1.5"}
            ],
            "score_mode": "total"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

响应:

{
    "_shards": {
        "failed": 0,
        "successful": 5,
        "total": 5
    },
    "hits": {
        "hits": [
            {
                "_id": "3",
                "_index": "test",
                "_score": 0.23837921,
                "_source": {
                    "tags": [
                        "c",
                        "b"
                    ],
                    "title": "3"
                },
                "_type": "bit"
            },
            {
                "_id": "1",
                "_index": "test",
                "_score": 0.042195037,
                "_source": {
                    "tags": [
                        "a",
                        "b",
                        "c"
                    ],
                    "title": "1"
                },
                "_type": "bit"
            }
        ],
        "max_score": 0.23837921,
        "total": 2
    },
    "timed_out": false,
    "took": 3
}
Run Code Online (Sandbox Code Playgroud)

仍然得到错误的顺序,并且缺少一个结果。obj_1应该在obj_3之前(因为它同时具有两个标签),并且obj_2仍然完全丢失。怎么会这样?

Rom*_*mko 1

我的例子有两个问题。

  1. “a”术语是一个停用词,因此它被丢弃,只使用“c”术语。
  2. custom_filters_score 查询必须包含“constant_score”查询,以便所有术语在提升之前具有相同的权重。

现在可以了!