【问题标题】:Elasticsearch: match every position only onceElasticsearch:每个位置只匹配一次
【发布时间】:2014-02-05 11:36:56
【问题描述】:

在我的 Elasticsearch 索引中,我的文档在同一位置有多个标记。

当我在每个位置至少匹配一个标记时,我想取回一个文档。 令牌的顺序并不重要。 我怎样才能做到这一点?我使用 Elasticsearch 0.90.5。

示例:

我这样索引一个文档。

{
    "field":"red car"
}

我使用同义词标记过滤器,在与原始标记相同的位置添加同义词。 所以现在在这个领域,有2个职位:

  • 位置 1:“红色”
  • 位置 2:“汽车”、“汽车”

我现在的解决方案:

为了能够确保所有位置都匹配,我也索引了最大位置。

{
    "field":"red car",
    "max_position": 2
}

我有一个自定义相似度,它从 DefaultSimilarity 扩展并返回 1 tf()、idf() 和 lengthNorm()。结果分数是字段中匹配项的数量。

查询:

{
    "custom_score": {
        "query": {
             "match": {
                 "field": "a car is an automobile"
             }
        },
        "_script": "_score*100/doc[\"max_position\"]+_score"
    },
    "min_score":"100"
}

我的解决方案有问题:

上面的搜索不应该匹配文档,因为查询字符串中没有标记“red”。但它匹配,因为 Elasticsearch 将 car 和 motor 的匹配数计为两个匹配项,因此得分为 2,导致脚本得分为 102,满足“min_score”。

【问题讨论】:

    标签: lucene position elasticsearch


    【解决方案1】:

    如果您需要保证 100% 匹配 查询条件,您可以使用 minimum_should_match。这是比较常见的情况。


    不幸的是,在您的情况下,您希望提供 100% 匹配的索引词。为此,您必须下拉到 Lucene 级别并编写自定义 (java - here's boilerplate you can fork) Similarity 类,因为您需要访问不暴露给 Query DSL 的低级索引信息:

    在查询记分器中扫描的每个文档/字段:

    然后,您的自定义相似度(您甚至可以扩展 DefaultSimilarity)将需要检测 术语匹配 总术语的查询并将它们的分数乘以零。

    由于在这个评分级别已经进行了查询和索引时间分析,索引词的总数将已经扩展为包括同义词,查询词也应如此,避免误报“a car是汽车” 上面的问题。

    【讨论】:

      猜你喜欢
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多