【问题标题】:Query elasticsearch to make all analyzed ngram tokens to match查询 elasticsearch 以使所有分析的 ngram 标记匹配
【发布时间】:2018-05-16 12:20:53
【问题描述】:

我使用 nGram 分析器(仅发出三元组)索引了一些数据,以解决 compound words problem exactly as described at the ES guide

但这并不像预期的那样工作:相应的匹配查询将返回至少匹配一个 nGram-token(每个单词)的所有文档。

例子:

让我们使用 nGram 分析器来获取这两个带有单个字段的索引文档:

POST /compound_test/doc/_bulk
{ "index": { "_id": 1 }}
{ "content": "elasticsearch is awesome" }
{ "index": { "_id": 2 }}
{ "content": "some search queries don't perform good" }

现在,如果我运行以下查询,我会得到两个结果:

"match": {
  "content": {
    "query": "awesome search",
    "minimum_should_match": "100%"
  }
}

由此构造的查询可以这样表示:

(awe OR wes OR eso OR ome) AND (sea OR ear OR arc OR rch)

这就是第二个文档匹配的原因(它包含“some”和“search”)。它甚至会匹配包含标记“som”和“rch”的单词的文档。

我真正想要的是一个每个分析的标记必须匹配的查询(在最好的情况下取决于最小应该匹配),所以是这样的:

"match": {
  "content": {
    "query": "awe wes eso ome sea ear arc rch",
    "analyzer": "whitespace", 
    "minimum_should_match": "100%"
  }
}

..实际上没有“从手”创建该查询/在客户端对其进行预分析。

可以在https://pastebin.com/97QxfaSb找到重现该行为的所有设置和数据

有这种可能吗?

【问题讨论】:

    标签: elasticsearch tokenize n-gram


    【解决方案1】:

    在写问题的时候,无意中找到了答案:

    如果 ngram 分析器使用 ngram-filter 生成三元组(如指南中所述),它的工作方式如上所述。 (我猜是因为实际的标记不是单个 ngram,而是所有创建的 ngram 的组合)

    为了实现想要的行为,分析器必须使用 ngram 标记器:

    "tokenizer": {
      "trigram_tokenizer": {
        "type": "ngram",
        "min_gram": 3,
        "max_gram": 3,
        "token_chars": [
          "letter",
          "digit"
        ]
      }
    },
    "analyzer": {
      "trigrams_with_tokenizer": {
        "type": "custom",
        "tokenizer": "trigram_tokenizer" 
      }
    }
    

    使用这种方式生成令牌将在查询该字段时产生预期的结果。

    【讨论】:

    • 是的,我正要准确指出这个问题,即您应该使用 ngram 标记器而不是 ngram 标记过滤器,因为您的示例与 ES 指南中的示例不同(示例显示复合词,而您的示例没有)。很高兴你知道了!
    • 我猜“elasticsearch”是一个复合词.. ;) 好吧,我想用英文保持这个例子.. 顺便说一下,ngrams 也是处理小错别字的好方法。跨度>
    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 2017-02-16
    • 2020-12-27
    • 1970-01-01
    相关资源
    最近更新 更多