【问题标题】:ElasticSearch use "best match" of ngram terms instead of "synonym"?ElasticSearch 使用 ngram 术语的“最佳匹配”而不是“同义词”?
【发布时间】:2017-12-09 13:17:33
【问题描述】:

是否可以告诉 ElasticSearch 使用所有克的“最佳匹配”而不是使用克作为同义词?

默认情况下,ElasticSearch 使用grams 作为同义词并返回匹配不佳的文档。最好用例子来展示,假设我们有两个人在索引中:

alice wang
sarah kerry

我们搜索ali12345:

{
  query: {
    bool: {
      should: {
        match: { name: 'ali12345' }
      }
    }
  }
}

它会返回alice wang。

这怎么可能?因为默认情况下 ElasticSearch 使用grams 作为同义词,所以,即使只有一个gram 匹配 - 文档也会被匹配。

如果您检查查询,您会发现它将克视为同义词

...
"explanation": {
  "value": 5.274891,
  "description": "weight(Synonym(name: ali name:li1 name:i12 name:123 name:234 name:345 ) in 0) [PerFieldSimilarity], result of:",
...

我想知道是否可以告诉它使用“最佳匹配”查询,以实现类似:

{
  query: {
    bool: {
      should: [
        { term: { body: 'ali' }},
        { term: { body: 'li1' }},
        { term: { body: 'i12' }},
        { term: { body: '123' }},
        { term: { body: '234' }},
        { term: { body: '345' }},
      ],
      minimum_should_match: '75%'
    }
  }
}

问题:

  1. 当然可以手动生成此查询,但是您必须手动应用 ngram 解析和其他分析器管道。所以我想知道它是否可以由 ElasticSearch 完成?

  2. 当有几十克/词时,这种长字符串查询的性能如何?它是否会使用一些智能优化,例如搜索类似文档(请参阅more_like_this) - 当它尝试不使用所有术语而只使用最高 tf-idf 的术语时?

附:

索引配置

{
  mappings: {
    object: {
      properties: {
        name: {
          type:     'text',
          analyzer: 'trigram_analyzer'
        }
      }
    }
  },

  settings: {
    analysis: {
      filter: {
        trigram_filter: { type: 'ngram', min_gram: 3, max_gram: 3 }
      },
      analyzer: {
        trigram_analyzer: {
          type:        'custom',
          tokenizer:   'keyword',
          filter:      [ 'trigram_filter' ]
        }
      }
    }
  }
}

【问题讨论】:

  • 你到底想做什么?您当前使用的match 查询方法有什么问题?
  • @AndreiStefan 默认的match 将找到alice wang 作为ali12345 查询的匹配项。这显然是错误的。此外(虽然我不确定)相关性以类似的破坏方式计算。
  • 它发现ali12345是因为ngrams。如果您不希望 ali12345 与 ngrams 匹配,那么呢?
  • 它发现ali12345是因为ngrams。如果您不希望 ali12345 与 ngrams 匹配,那么呢?
  • @AndreiStefan 有很多方法可以使用 ngram。我想要类似于余弦相似度的东西。

标签: elasticsearch n-gram trigram


【解决方案1】:

我知道这个问题很老了,但以防万一......

您应该能够在 trigram 查询中使用 minimumShouldMatch 子句来指定必须匹配多少 trigram 才能将记录视为命中。您可以使用“3

【讨论】:

    【解决方案2】:

    也许你已经找到了原因,但是ali12345 与alice wang 匹配,因为搜索时的分析器与用于索引时间的分析器相同,包括 ngram。

    这样:

    在索引时:对于文本 alice wang,创建这些术语 [ali, lic, ice, ...]

    在搜索时:对于文本 ali12345,会创建这些术语 [ali, li1, i12, ...]

    如我们所见,我们与术语 ali 匹配

    为避免此问题,ElasticSearch 提供了为搜索时间指定不同分析器的可能性。在字段name 的映射中,您可以添加另一个属性search_analyzer,它通常与主analyzer 非常相似,但没有ngram 标记过滤器。这将防止在搜索分析期间生成 [ali, li1, i12] 导致 0 匹配到 alice wang

    请随时在此页面上查看更多详细信息和说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 2018-02-04
      • 1970-01-01
      相关资源
      最近更新 更多