MongoDB全文搜索不使用索引
我们使用mongoDB全文搜索在数据库中查找产品。 不幸的是,它的速度太慢了。 该集合包含89.114.052个文档,我怀疑没有使用全文索引。 使用explain()执行搜索时,nscannedObjects返回133212。 如果使用索引,这不应该是0吗 我的索引:MongoDB全文搜索不使用索引,mongodb,search,indexing,mongodb-query,full-text-search,Mongodb,Search,Indexing,Mongodb Query,Full Text Search,我们使用mongoDB全文搜索在数据库中查找产品。 不幸的是,它的速度太慢了。 该集合包含89.114.052个文档,我怀疑没有使用全文索引。 使用explain()执行搜索时,nscannedObjects返回133212。 如果使用索引,这不应该是0吗 我的索引: { "v" : 1, "key" : { "_fts" : "text", "_ftsx" : 1 }, "name" : "textIndex", "ns"
{
"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
}
请看一下您提出的问题: “…该集合包含89.114.052个文档,我怀疑未使用全文索引…” 您仅对133212个文档进行“nscanne”。当然使用索引。如果不是,则89114052个文档(因为这是英语区域设置而不是德语)将在“nScanned”中报告,这意味着不使用索引 你的查询很慢。看来您的硬件无法在内存中保存1333212个文档,或者使用超高速磁盘有效地“分页”。但这不是MongoDB的问题,而是你的问题 您有超过100000个文档与您的查询匹配,即使您只需要100个文档,您也需要接受这一点,并且MongoDB不会在匹配了100个文档和收益控制后“放弃”。这里的查询模式查找所有匹配项,然后将“限制”应用于光标,以便只返回最近的匹配项 也许在将来的某个时候,“文本”功能可能会允许您执行在的聚合版本中可以执行的操作,并为“分数”指定“最小”和“最大”值,以改进结果。但目前情况并非如此
因此,如果您的问题是在89000000多个文档中匹配100000多个文档的结果较慢,请升级您的硬件或使用外部文本搜索解决方案。如果索引使用率较高,nscannedObjects实际上不是100个吗?我不知道mongoDB的详细内部实现,但只使用索引字段,它应该是0,因为没有扫描任何文档。他们可能会再次检查结果中的所有文档,以排除由于类似的词干而添加的结果。但是133212个文档,只有100个真正匹配?您的限制是100,这就是为什么n是100正确的。但它是关于nscannedObjects/nscanned以及是否使用索引的。我只使用了limit(100)来加快速度,因为没有排序…仍然需要大约20秒。实际上,由于我自己的测试,这让我有点困惑。在我自己的测试中,如果对索引正确应用了限制,那么扫描的对象也应该是100。如果MongoDB就是这样工作的,那么就可以了。通过阅读文档,这一点并不清楚。所以regexp搜索也会以同样的方式工作,对吗?也许我们不得不接受mongo文本搜索对于如此数量的文档是不可行的。硬件是最新的。“即使是我们的第二台搜索服务器使用SSD的速度也令人难以置信。”托比亚斯克说。除非您的$regex搜索被锚定为字符串的开头,否则您至少需要完整的索引扫描。但关键是。再快的磁盘也比不上在内存中安装工作数据。因此,您需要的是RAM,或者分片,以便使用RAM在服务器之间分割工作数据。这同样适用于外部文本解决方案,尽管它们通常会更加优化。我完全同意。但目前,200 GB以上的RAM还不是很便宜。对于我们的新后端,我们将切换到elasticsearch,因为mongodb全文搜索到目前为止还没有那么强大。也许在将来。我只是想找到一种方法,让它足够快,直到新的后端准备好。