【问题标题】:Filter document to match either of the two fields in nested elasticsearch field过滤文档以匹配嵌套弹性搜索字段中的两个字段中的任何一个
【发布时间】:2019-03-10 23:21:56
【问题描述】:

我在 elasticsearch 的文档中有一个名为 tags 的字段,结构如下。

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

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

我尝试使用术语过滤器,但它只是做或。有没有什么技术可以实现上述目标。

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

【问题讨论】:

  • tag 是嵌套字段吗?
  • 你能分享你的索引映射吗?
  • 嗨@Sudip,你检查我的答案了吗?有帮助吗?

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


【解决方案1】:

问题分析

让我们在以下子问题中解决您的问题:

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

解决方案

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

为了解决(P1.2),我会将tags.idtags.related 的所有值复制到一个新的自定义字段中,例如tags.all。这可以使用copy_to 属性来实现,如下所示:

{
  "mappings": {
    "_doc": {
      "properties": {
        "tags": {
          "properties": {
            "id": { 
              "type": "long",
              "copy_to": "tags.all"
            },
            "related": { 
              "type": "long",
              "copy_to": "tags.all"
            }
          }
        }
      }
    }
  }
}

然后,要解决 (P1),您可以针对 tags.all 运行 terms_set 查询。例如,

{
  "query": {
    "terms_set": {
      "tags.all": {
        "terms": [ 9, 8 ],
        "minimum_should_match_script": {
          "source": "2"
        }
      }
    }
  }
}

最后,要解决 (P2),您可以创建一个布尔型 should 查询,包括 (i) 上述 terms_set 查询,(ii) 针对 @ 的 terms 查询仅 987654337@,具有更高的升压因子。即,

{
  "query": {
    "bool": {
      "should": [
        {
          "terms_set": {
            "tags.all": {
              "terms": [ 9, 8 ],
              "minimum_should_match_script": {
                "source": "2"
              }
            }
          }
        },
        {
          "terms": {
            "tags.id": {
              "value": [ 9, 8 ],
              "boost": 2
            }
          }
        }
      ]
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2016-04-10
    • 1970-01-01
    相关资源
    最近更新 更多