Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB全文搜索不使用索引_Mongodb_Search_Indexing_Mongodb Query_Full Text Search - Fatal编程技术网

MongoDB全文搜索不使用索引

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"

我们使用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
}

请看一下您提出的问题:

“…该集合包含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全文搜索到目前为止还没有那么强大。也许在将来。我只是想找到一种方法,让它足够快,直到新的后端准备好。