当前位置: 首页 > 知识库问答 >
问题:

elasticsearch ngrams:为什么匹配的是较短的令牌而不是较长的令牌?

魏雅惠
2023-03-14

我有一个带有以下映射和分析器的索引:

settings: {
    analysis: {
      char_filter: {
        custom_cleaner: {
          # remove - and * (we don't want them here)
          type: "mapping",
          mappings: ["-=>", "*=>"]
        }
      },
      analyzer: {
        custom_ngram: {
          tokenizer: "standard",
          filter: [ "lowercase", "custom_ngram_filter" ],
          char_filter: ["custom_cleaner"]
        }
      },
      filter: {
        custom_ngram_filter: {
          type: "nGram",
          min_gram: 3,
          max_gram: 20,
          token_chars: [ "letter", "digit" ]
        }
      }
    }
  },
  mappings: {
    attributes: {
      properties: {
        name: { type: "string"},
        words: { type: "string", similarity: "BM25", analyzer: "custom_ngram" }
      }
    }
  }
}

我在索引中有以下2个文档:

“name”:“shirts”,“words”:[“shirt”]

“名称”:“t恤”,“单词”:[“t恤”]

我以如下方式执行多拍片查询

"query": {

            "multi_match": {
               "query": "t-shirt",
               "fields": [
                  "words",
                  "name"
               ],
               "analyzer": "custom_ngram"
            }

   }

问题:

衬衫的得分为1.17,而T恤的得分为0.8。那是为什么,我怎样才能做到那件T恤(直接搭配)有更高的分数?

我需要ngrams用于另一个用例,在那里我必须检测包含匹配。(衬衫是在肌肉衬衫,…)所以我不能跳过ngrams,我想。

共有1个答案

姜兴业
2023-03-14

我认为发生这种情况是因为您使用了standardtokenizer,它将字符串“t-shirt”标记为标记“t”和“shirt”。然而,“t”比最小gram大小短,因此不会从它生成令牌。因此,在每种情况下都得到相同的匹配,但是带有T恤的文档较长,因此得分略低。

通过使用Explain API,您可以获得关于文档为什么会得到它们得到的分数的详细信息。

您确定需要使用ngrams吗?您的示例中,“muscess-shirt”中的“shirt”应该由standardanalyzer处理得很好,它将在连字符上标记。

 类似资料:
  • 我有一个与YouTube直播API集成的程序。它运行在计时器上,所以我相对容易编程,每50分钟用一个刷新令牌获取一个新的访问令牌。我的问题是,为什么? 当我使用 YouTube 进行身份验证时,它给了我一个刷新令牌。然后,我使用此刷新令牌大约每小时获取一次新的访问令牌。如果我有刷新令牌,我可以随时使用它来获取新的访问令牌,因为它永远不会过期。因此,我认为这比从一开始就给我一个访问令牌而不打扰整个刷

  • 在新的Firebase中,在Notification下,他们提到开发者可以向特定设备发送通知。为此,它在控制台中请求FCM令牌。它到底是什么?我怎样才能得到那个令牌?

  • 问题内容: 从www.JavaPractices.com复制的此代码中的令牌是什么意思?当我用更通用的泛型类型替换它时,它无法编译。(错误:T无法解析为类型。)为什么? 编辑:当然,当我们使用类似的通用类型标记时,它必须出现在类声明中。这里也没有,也没有在类的声明,但它仍然可以编译和运行正常。 问题答案: 它无法编译,因为您的类不是通用的(也不是您的任何方法)。在此特定示例中,小丑(?)表示Sch

  • 标准的TestCase之一是,lexer应该从中生成令牌流。不幸的是,由于ANTLR优先匹配较长的令牌,它生成令牌流,这将导致解析器引发错误。 是否可以先让ANTLR4 lexer尝试使用较短的令牌进行匹配?向添加lookahead-type规则并不是一个很好的解决方案,因为我需要考虑各种潜在的词法冲突(例如,被命名为,而不是,等等)。 编辑: 但这并不是一个真正的可扩展或可维护的解决方案,而且还

  • 问题内容: 在Emacs中匹配括号的命令是什么(与Vim 中的命令等效)? 问题答案: 见中所述5.27如何显示其匹配括号我在看的人吗?

  • 问题内容: 我们尝试使用以下Java代码从字符串转换为: 我们得到一个长度为22个字节的字节数组,我们不确定此填充来自何处。如何获得长度为20的数组? 问题答案: 亚历山大(Alexander)的答案解释了为什么存在它,但没有解释如何摆脱它。您只需要在编码名称中指定所需的字节序即可: