在 MongoDB 中,如果我的文本包含 UUID,如何提取文本?

In MongoDB how is text stemmed if my text contains a UUID?

我正在调查 MongoDB 中某个集合的缓慢更新。
以前的同事选择了 _id 字段的字符串类型,并在其他字符串字段上建立索引。

现在我知道文本索引是有词干的,我可以想象当文档更新时这会非常繁重。
_id 字段的内容也是一个 UUID。现在我不完全明白词干是如何工作的,但是猜测UUID(part1-part2-part3-part4-etc)的每个部分都成为索引中的唯一条目,导致查询很慢。

有人可以解释词干提取如何处理包含 UUID 的文本吗?

词干提取仅适用于属于 text index 的字符串字段。默认 _id 索引的选项无法更改,并且 _id 索引不能是 text 索引,因此词干提取不适用于此上下文。 _id 值是索引中的单个条目,它必须是唯一的。

Now I don't fully understand how stemming works, but guessing each part of the UUID (part1-part2-part3-part4-etc) becomes a unique entry in the index, causing queries to be slow.

Stemming 使用特定于语言的启发式方法将单词缩减为预期的词根形式。词干库具有典型的语言变形规则概念,但对有效单词或语法没有任何理解。在 text 索引定义中包含 UUID 字段(或其他随机非语言字符串)通常没有意义。

MongoDB text 索引使用开源 Snowball library 进行词干提取。

Can someone explain how stemming would work on text which contains a UUID?

最好的方法是 explain MongoDB $text queries to see exactly how they are parsed. However, there's also an online Snowball demo 如果您想快速尝试不同语言的词干提取算法,这会很有用。

MongoDB text 索引或 $text 查询会将空格和大多数标点字符(包括连字符)视为单词分隔符,因此 part1-part2-part3-part4-etc 将被拆分为 5 条款。每个术语都将被阻止,任何重复的术语都将被忽略。由随机字母或 part1 之类的值组成的术语不会有词干启发式意外匹配之外的词根形式。

例如,英文:

  • 以单个 s 结尾的单词通常是复数。如果你随便编一个词,比如 part4s ,它会变成 part4.
  • ss结尾的单词一般都不是复数,所以part4ss会保持不变。

您可以通过解释文本搜索查询并查看 parsedTextQuery.

的字词来了解词组是如何被词干化的

使用 mongo shell:

> db.stores.createIndex( { name: "text", description: "text" } )
> db.stores.find( { $text: { $search: "part1-part2-part3-part4-etc-part4s-part4ss" } } ).
       explain().queryPlanner.winningPlan.parsedTextQuery
{
    "terms" : [
        "etc",
        "part1",
        "part2",
        "part3",
        "part4",
        "part4ss"
    ],
    "negatedTerms" : [ ],
    "phrases" : [ ],
    "negatedPhrases" : [ ]
}

我向您的示例 UUID 添加了 part4spart4ss。由于 part4s 源于 part4(这已经是一个唯一的术语),您会注意到我的查询只找到 6 个术语而不是 7 个。