MongoDB $文本搜索如何工作?

Posted

技术标签:

【中文标题】MongoDB $文本搜索如何工作?【英文标题】:How does MongoDB $text search works? 【发布时间】:2019-05-08 04:50:46 【问题描述】:

我在我的事件集合中插入了以下值

db.events.insert(
   [
      _id: 1, name: "Amusement Ride", description: "Fun" ,
      _id: 2, name: "Walk in Mangroves", description: "Adventure" ,
      _id: 3, name: "Walking in Cypress", description: "Adventure" ,
      _id: 4, name: "Trek at Tikona", description: "Adventure" ,
      _id: 5, name: "Trekking at Tikona", description: "Adventure" 
   ]
)

我还通过以下方式创建了一个索引:

db.events.createIndex(  name: "text"  )

现在当我执行以下查询(搜索 - 步行)时:

db.events.find(
    '$text': 
        '$search': 'Walk'
    ,
)

我得到了这些结果:

 _id: 2, name: "Walk in Mangroves", description: "Adventure" ,
 _id: 3, name: "Walking in Cypress", description: "Adventure" 

但是当我搜索 Trek 时:

db.events.find(
    '$text': 
        '$search': 'Trek'
    ,
)

我只得到一个结果:

 _id: 4, name: "Trek at Tikona", description: "Adventure" 

所以我的问题是为什么它会导致:

 _id: 4, name: "Trek at Tikona", description: "Adventure" ,
 _id: 5, name: "Trekking at Tikona", description: "Adventure" 

当我搜索 walk 时,结果是包含 walk 和 walk 的文档。但是当我搜索 Trek 时,它只找到了包含 trek 在内的文档,而它应该同时导致了 trek 和 trekking

【问题讨论】:

因为“Trek”的 textScore 与其他人不匹配。 【参考方案1】:

MongoDB 文本搜索使用Snowball stemming library 根据通用语言规则将单词缩减为预期的根形式(或词干)。算法词干提取提供了快速的减少,但语言有可能影响准确性的例外情况(例如不规则或矛盾的动词变位模式)。 Snowball introduction 很好地概述了算法词干提取的一些限制。

您的walking 示例源于walk 并按预期匹配。

但是,您的 trekking 示例源于 trekk,因此与您的搜索关键字 trek 不匹配。

您可以通过解释您的查询并查看显示所使用的词干搜索词的 parsedTextQuery 信息来确认这一点:

db.events.find($text: $search: 'Trekking' ).explain().queryPlanner.winningPlan.parsedTextQuery

​   "terms" : [
​       "trekk"
​   ],
​   "negatedTerms" : [ ],
​   "phrases" : [ ],
​   "negatedPhrases" : [ ]

您还可以使用在线 Snowball Demo 或通过查找适合您首选编程语言的 Snowball 库来检查预期的 Snowball 词干。

要解决通常可能会影响您的用例的异常情况,您可以考虑在文本索引中添加另一个字段,其中包含关键字以影响搜索结果。对于此示例,您可以将 trek 添加为关键字,以便描述为 trekking 的事件也会在您的搜索结果中匹配。

还有其他更准确的变形方法,通常称为词形还原。词形还原算法更复杂,并开始进入natural language processing 的领域。如果您想在应用程序中实现更高级的文本搜索,您可以利用许多开源(和商业)工具包,但这些超出了 MongoDB 文本搜索功能的当前范围。

【讨论】:

以上是关于MongoDB $文本搜索如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongodb / mongoose 中使用“$text query and $or”进行多文本搜索?

MongoDB 全文和部分文本搜索

使用聚合管道进行文本搜索 - MongoDB / PHP

错误:未启用文本搜索:- 在 mongodb

MongoDB / Mongoose - 数组内的文本搜索

如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?