gpt4 book ai didi

MongoDB 德语文本索引

转载 作者:IT老高 更新时间:2023-10-28 13:15:56 25 4
gpt4 key购买 nike

在我的文章集合中,我有一个文本索引:

{
"v" : 1,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "title_text_abstract_text_body_text",
"ns" : "foo.articles",
"weights" : {
"abstract" : 1,
"body" : 1,
"title" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}

在我的文章集中,我有一个这样的条目:
{
"_id" : ObjectId("5477c28c807a9cd660ccd567"),
"title" : "Hallo Welt!",
"author" : "foo",
"publishDate" : ISODate("2014-11-28T17:00:00Z"),
"language" : "de",
"abstract" : "Mein erster Artikel!",
"body" : "Dieser Artikel ist in deutscher Sprache.",
"__v" : 0
}

(在 abstractbody 中实际上有不同的值,为简洁起见,假设是上面的值)

当我尝试搜索这篇文章时:
db.articles.find({$text: {$search: 'Welt'}})

它确实被发现了。

但:
当我尝试搜索这篇文章时:
db.articles.find({$text: {$search: 'Sprache'}})

我没有结果。但是后来我改了 languageennone我确实得到了这篇文章,结果是完全相同的查询。

我究竟做错了什么?

编辑 :
根据评论中的要求,这里是导致上述行为的确切命令。一开始就应该这样做,抱歉。
> db.test.drop()
true
> db.test.insert({language: "de", body: "vermutlich", title: "Artikel"})
WriteResult({ "nInserted" : 1 })
> db.test.ensureIndex({body: "text", title: "text"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.test.find({$text: {$search: 'vermutlich'}})
> db.test.find({$text: {$search: 'Artikel'}})
{ "_id" : ObjectId("54ea86d6c9ec98269e022c67"), "language" : "de", "body" : "vermutlich", "title" : "Artikel" }
> db.version()
2.6.5

我还尝试再次更改语言:
> db.test.update({}, {$set: {language: "en"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.test.find({$text: {$search: 'Artikel'}})
{ "_id" : ObjectId("54ea86d6c9ec98269e022c67"), "language" : "en", "body" : "vermutlich", "title" : "Artikel" }
> db.test.find({$text: {$search: 'vermutlich'}})
{ "_id" : ObjectId("54ea86d6c9ec98269e022c67"), "language" : "en", "body" : "vermutlich", "title" : "Artikel" }

编辑:
好的,所以我只是尝试重建 this example.
但我还添加了一个德语引用,所以这就是我所做的:
> db.test.drop()
true
> db.test.insert({ language: "portuguese", original: "A sorte protege os audazes.", translation: [{ language: "english", quote: "Fortune favors the bold."},{ language: "spanish", quote: "La suerte rotege a los audaces."}]})
WriteResult({ "nInserted" : 1 })
> db.test.insert({ language: "spanish", original: "Nada hay más surrealista que la realidad.", translation:[{language: "english",quote: "There is nothing more surreal than reality."},{language: "french",quote: "Il n'y a rien de plus surréaliste que la réalité."}]})
WriteResult({ "nInserted" : 1 })
> db.test.insert({ original: "is thisdagger which I see before me.", translation: {language: "spanish",quote: "Es este un puñal que veo delante de mí." }})
WriteResult({ "nInserted" : 1 })
> db.test.insert({original: "Die Geister, die ich rief...", language: "german", translation: {language: "english", quote: "The spirits that I've cited..."}})
WriteResult({ "nInserted" : 1 })
> db.test.ensureIndex( { original: "text", "translation.quote": "text" } )
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}

然后我尝试了一些查询:
> db.test.count({$text: {$search: "delante"}})
1
> db.test.count({$text: {$search: "spirits"}})
1
> db.test.count({$text: {$search: "Geister"}})
0

结论:mongoDB 不支持德语?
这真的很令人沮丧

最佳答案

wdberkeley 是正确的,但我觉得有必要添加对 stemming 的快速解释因为我怀疑没有该领域经验的用户会明白要点。我还想强调一些替代方案和一般限制。

在许多语言中,由于语法规则,单词会发生显着变化,例如对于德语单词“Geist”(心灵/幽灵/精神):

"Geist" (singular) -> "Geister" (plural) -> "Geistern" (plural accusative)

这种效果在英语中也是众所周知的,但不太明显,例如:
"house" -> "houses" // "mouse" -> "mice" // "notable" -> "notably"

通常,我们希望搜索忽略该本地语法结构,因此如果我们要查找 "Geist"它应该找到上面的任何一个词。正确地做到这一点极具挑战性,因为语言规则很复杂,如果没有上下文,就不一定能确定正确的答案。

后缀剥离是一种常见且相对简单的方法,它假设某些结尾很可能确实只是结尾,并且可以删除以获得词干。有时,词干分析器会故意删除实际上属于词干的字母,例如 "notable" -> "notabl" .

由于引号的语言是已知的,正确的词干提取器将用于引号。这有效 - 使用您的数据:
> db.test.find({$text: {$search: 'Geist'}}).count()
1

现在你的问题是用户可能不是在寻找词干,而是在寻找派生形式,所以我们需要对输入应用相同的转换。关键问题是我们不知道首先应用了哪种转换。因此,您正在尝试通过添加一个变量来做一些已经很复杂的事情。

好消息是 there is snowball ,这是 MongoDB 和其他搜索系统(如 SolR)使用的词干分析器。它在 BSD 许可下可用,并被移植到多种语言,因此可以在客户端代码中执行数据库所做的相同操作。这样,我们不会将数据库视为黑盒,但我们还将我们的客户端代码与数据库的实现细节结合起来......选择你的毒药。

例如,我们可以遍历所有词干分析器并查看哪个改变了输入,但这可能会导致错误肯定,因为该词可能已经是词干并且来自另一种语言的词干分析器将其缩短(德语词干分析器: 'mice' -> 'mic') .

至少,如果我们采用词干分析器的一组不同的响应,我们需要进行的查询数量会大大减少。

或者,您可以查阅单词列表来猜测此查询可能使用的语言。

即使付出了额外的努力, 也很重要。了解限制 通过简单的后缀剥离完成的词干提取。例如,在查找“mouse”时不会找到“mice”,即使使用英文词干分析器也不会,因为词干分析器假定词干较短。如果文本不是真正使用他们假定的语言,事情会变得更糟(尤利西斯......)

换句话说:一个真正好的自由文本搜索需要的不仅仅是词干,而且跨语言查询会增加这一点。不同的搜索数据库 is not a panacea - 问题在问题空间中根深蒂固...

编辑:
ElasticSearch has a nice comprehensive explanation of stemming (写完答案后我一直在寻找这些)

编辑2:

Why can't MongoDB simply use differently stemmed words?



转换仅在插入或更新数据库中的文本时应用。该查询只是查找词干的匹配项。本质上,索引是由词干构成的。你想要的东西每次都需要遍历整个集合。那将是非常低效的并且违背了索引的目的。您可以做的是按照建议在客户端代码中执行该步骤。

Why can't I just use $or with twice searching the text-index



AFAIK,这是查询引擎的限制 - 可能与排名有关,因为根据两个不同的输入进行良好的评分没有多大意义。但是您可以简单地运行两个查询并在客户端合并结果。

关于MongoDB 德语文本索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28646646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com