过滤文档以匹配嵌套elasticsearch字段中的两个字段之一

时间:2019-03-06 04:20:21

标签: elasticsearch elasticsearch-dsl elasticsearch-dsl-py

我在具有以下结构的elasticsearch文档中有一个名为标签的字段。

tags = [
    {
        "id": 10,
        "related": [9, 8, 7]
    }
]

我现在运行带有列表的过滤器。例如[10, 9]。我只想过滤那些包含ID或相关列表中所有项目的文档。如果我使用[9, 8]搜索,则应返回上述文档。如果我使用[9, 12]进行搜索,则不应返回上述文档,因为ID或相关名称中均不存在12。

我尝试过使用条件过滤器,但是它只是这样做了。有什么技术可以实现上述目标。

此外,与包含related中包含给定项目的项相比,我想为包含ID中给定项的文档提供更高的排名。

1 个答案:

答案 0 :(得分:1)

问题分析

让我们通过以下子问题来解决您的问题:

  • (P1)检查数组中提供的 all 术语是否出现在tags.idtags.related中。这可以进一步分解为:
    • (P1.1)检查数组中提供的所有所有字段中是否存在
    • (P1.2)检查数组中提供的所有术语是否分布在不同字段
  • (P2)为具有任何tags.id条款的文档分配更高的分数

解决方案

要解决(P1.1),您可以使用Elasticsearch v6.6中提供的terms_set查询(请参见documentation)。

要解决(P1.2),我需要将tags.idtags.related的所有值复制到一个新的自定义字段中,例如{{1 }}。可以使用tags.all属性,如下所示:

copy_to

然后,要解决(P1),您可以针对{ "mappings": { "_doc": { "properties": { "tags": { "properties": { "id": { "type": "long", "copy_to": "tags.all" }, "related": { "type": "long", "copy_to": "tags.all" } } } } } } } 运行terms_set查询。例如,

tags.all

最后,要解决(P2),您可以创建一个布尔{ "query": { "terms_set": { "tags.all": { "terms": [ 9, 8 ], "minimum_should_match_script": { "source": "2" } } } } } 查询,其中包括(i)上述should查询,(ii){{ 1}}仅针对具有较高提升因子的terms_set进行查询。即

terms