【问题标题】:MongoDB fulltext search not using indexMongoDB全文搜索不使用索引
【发布时间】:2014-09-09 14:58:38
【问题描述】:

我们使用 mongoDB 全文搜索在我们的数据库中查找产品。 不幸的是,它慢得令人难以置信。 该集合包含 89.114.052 个文档,我怀疑未使用全文索引。 使用 explain() 执行搜索,nscannedObjects 返回 133212。 如果使用索引,这不应该是 0 吗?

我的索引:

{
    "v" : 1,
    "key" : {
        "_fts" : "text",
        "_ftsx" : 1
    },
    "name" : "textIndex",
    "ns" : "search.products",
    "weights" : {
        "brand" : 1,
        "desc" : 1,
        "ean" : 1,
        "name" : 3,
        "shop_product_number" : 1
    },
    "default_language" : "german",
    "background" : false,
    "language_override" : "language",
    "textIndexVersion" : 2
}

完整的测试搜索:

> db.products.find({ $text: { $search: "playstation" } }).limit(100).explain()
{
    "cursor" : "TextCursor",
    "n" : 100,
    "nscannedObjects" : 133212,
    "nscanned" : 133212,
    "nscannedObjectsAllPlans" : 133212,
    "nscannedAllPlans" : 133212,
    "scanAndOrder" : false,
    "nYields" : 1041,
    "nChunkSkips" : 0,
    "millis" : 105,
    "server" : "search2:27017",
    "filterSet" : false
}

【问题讨论】:

  • 如果有有效的索引使用,nscannedObjects 实际上不会是 100?
  • 我不详细了解mongoDB的内部实现,但是只使用索引字段,应该是0,因为没有扫描任何文档。他们可能会再次检查结果中的所有文档,以排除由于相似词干而添加的结果。但是 133212 个文档中只有 100 个真正匹配?
  • 你的限制是 100,这就是为什么 n 是 100
  • 正确。但它是关于 nscannedObjects / nscanned 以及是否使用索引。我只使用了 limit(100) 让它更快一点,因为没有排序......仍然需要大约 20 秒。
  • 实际上,由于我自己的测试,这让我有点困惑。在我自己的测试下,如果限制正确应用于索引,那么扫描的对象也应该是 100

标签: mongodb search indexing mongodb-query full-text-search


【解决方案1】:

请查看您提出的问题:

"....该集合包含 89.114.052 个文档,我怀疑没有使用全文索引 ...."

对于 133212 个文档,您只是“nScanned”。当然使用索引。如果不是,那么 89,114,052 文档(因为这是英语语言环境而不是德语)将在“nScanned”中报告,这意味着未使用索引。

您的查询速度很慢。好吧,您的硬件似乎无法完成将 1333212 个文档保存在内存中或以其他方式让超快速磁盘有效地“分页”的任务。但这不是 MongoDB 的问题,而是您的问题。

您有超过 100,000 个与您的查询匹配的文档,即使您只想要 100 个,那么您也需要接受这是它的工作原理,一旦您匹配了 100 个文档并进行了产量控制,MongoDB 就不会“放弃”。此处的查询模式会找到 所有 匹配项,然后将“限制”应用于光标,以便返回最新的。

也许在未来的某个时间,“文本”功能可能允许您执行您可以在 $geoNear 的聚合版本中执行的操作,并为“分数”指定“最小”和“最大”值,以便改善结果。但现在没有。

因此,如果您的问题是在超过 89,000,000 个文档中匹配超过 100,000 个文档时结果缓慢,请升级您的硬件或使用外部文本搜索解决方案。

【讨论】:

  • 如果这就是 MongoDB 的工作方式,那没关系。阅读文档并不清楚这一点。所以正则表达式搜索会以同样的方式工作,对吧?可能我们不得不接受 mongo 文本搜索对于这么多的文档是不切实际的。硬件是最新的。即使是我们的第二个搜索服务器,使用 SSD 的速度也非常慢。
  • @TobiasK。除非您的 $regex 搜索被锚定在字符串的开头,否则您至少会期待完整的索引扫描。但这就是重点。再多的快速磁盘都无法将工作数据放入内存中。因此,您需要的是 RAM,或者是分片,以便在服务器之间拆分工作数据,并覆盖 RAM。这同样适用于外部文本解决方案,尽管它们通常会更加优化。
  • 我完全同意。但是 > 200 GB RAM 目前并不那么实惠。对于我们的新后端,我们将切换到 elasticsearch,因为 mongodb 全文搜索目前还没有那么强大。也许在未来。我只是试图找到一种方法让它足够快,直到新的后端准备好。
猜你喜欢
  • 2018-10-26
  • 2014-05-10
  • 1970-01-01
  • 2012-05-12
  • 2018-09-27
  • 1970-01-01
  • 2018-11-23
  • 2014-01-11
相关资源
最近更新 更多