【问题标题】:Exact search in array object type using elasticsearch使用 elasticsearch 精确搜索数组对象类型
【发布时间】:2012-09-22 11:26:41
【问题描述】:

我正在寻找一种在弹性搜索中进行 精确 数组匹配的方法。 假设这些是我的文件:

{"id": 1, "categories" : ["c", "d"]}
{"id": 2, "categories" : ["b", "c", "d"]}
{"id": 3, "categories" : ["c", "d", "e"]}
{"id": 4, "categories" : ["d"]}
{"id": 5, "categories" : ["c", "d"]}

有没有办法搜索所有完全类别为“c”和“d”(文档 1 和 5)的文档,不多也不少?

作为奖励:搜索“其中一个”类别应该仍然是可能的(例如,您可以搜索“c”并获得 1、2、3 和 5)

有什么巧妙的办法解决这个问题?

【问题讨论】:

    标签: lucene elasticsearch


    【解决方案1】:

    如果您有一组离散的已知类别,则可以使用 bool 查询:

    "bool" : {
        "must" : {
            "terms" : { "categories" : ["c", "d"],
                 minimum_should_match : 2
             }
        },
        "must_not" : {
            "terms" : { "categories" : ["a", "b", "e"],
                 minimum_should_match : 1
             }
        }
    }
    

    否则,我认为最简单的方法可能是存储另一个字段作为类别关键字。

    {"id": 1, "categories" : ["c", "d"], "categorieskey" : "cd"}
    

    类似的东西。然后您可以轻松地使用术语查询精确地查询您想要的结果,例如:

    term { "categorieskey" : "cd" }
    

    您仍然可以进行非排他性搜索,例如;

    term { "categories" : "c" }
    

    查询必须同时存在的两个类别很容易,但要阻止任何其他潜在类别存在则有点困难。你可以做到,也许。您可能希望编写一个查询来查找两者的记录,然后对其应用过滤器以消除除指定类别之外的任何记录。据我所知,这并不是 Lucene 真正设计用来处理的一种搜索。

    老实说,我很难在这里找到一个好的过滤器。您可能需要一个脚本过滤器,或者您可以在检索到结果后对其进行过滤。

    【讨论】:

    • 很有趣,这正是我告诉他的 :)
    • 此查询不会运行。 minimum_match 似乎不是 TermsFilter 的有效参数。
    • @Conrad.Dean 谁说过要使用过滤器?
    • @femtoRgon 哦,哎呀。我太放大了。如果用"filter":{...} 而不是"query":{...} 包裹,则语法是相同的。 minimum_should_match 是术语查询中的有效参数 elasticsearch.org/guide/en/elasticsearch/reference/current/…
    • 啊,你说得对,应该是minimum_should_match。不确定这是 ElasticSearch 的变化还是错误,但更新肯定不会有坏处。谢谢。
    【解决方案2】:

    我为我们的用例找到了一个似乎可行的解决方案。它依赖于两个过滤器和我们想要匹配多少类别的知识。我们使用术语过滤器和脚本过滤器来检查数组的大小。在此示例中,marketBasketList 类似于您的类别条目。

    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "siteId": 4
              }
            },
            {
              "match": {
                "marketBasketList": {
                  "query": [
                    10,
                    11
                  ],
                  "operator": "and"
                }
              }
            }
          ]
        },
        "boost": 1,
        "filter": {
          "and": {
            "filters": [
              {
                "script": {
                  "script": "doc['marketBasketList'].values.length == 2"
                }
              },
              {
                "terms": {
                  "marketBasketList": [
                    10,
                    11
                  ],
                  "execution": "and"
                }
              }
            ]
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 2015-09-12
      • 2020-11-21
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多