【发布时间】:2015-07-31 13:14:34
【问题描述】:
想象一个包含大约 5,000,000 个文档的集合。我需要做一个basicCursor 查询来根据太多要索引的字段来选择~100 个文档。我们称之为basicCursorMatch。这将非常缓慢。
但是,我可以对一些索引进行bTreeCursor 查询,这会将我的搜索限制为大约 500 个文档。我们将此查询称为bTreeCursorMatch。
有没有办法可以直接在 bTreeCursorMatch 产生的光标或集合上执行此操作 basicCursorMatch?
我凭直觉尝试过
var cursor = collection.find(bTreeCursorMatch);
var results = cursor.find(basicCursorMatch);
类似于collection.find(bTreeCursorMatch).find(basicCursorMatch),似乎不起作用。
或者,我希望我能做这样的事情:
collection.aggregate([
{$match: bTreeCursorMatch}, // Uses index 5,000,000 -> 500 fast
{$match: basicCursorMatch}, // No index, 500 -> 100 'slow'
{$sort}
]);
.. 但似乎我也不能这样做。有没有其他方法可以做我想做的事?
我问的原因是因为第二个查询会有很大不同,而且我无法索引所有字段。但我确实想使用bTreeCursor 进行第一次查询,否则使用basicCursor 查询整个集合将永远需要。
更新
此外,通过用户输入,500 个文档的子选择将在会话期间以不同方式查询,其中包含不可预测的 basicCursor 查询,使用多个 $in $eq $gt $lt。但在此期间,bTreeCursor 子选择保持不变。我应该对每个用户查询都继续进行这两个查询,还是有更有效的方法来为这个集合保留reference?
【问题讨论】:
-
您不能连接查询,因为游标“活”在数据库中,它们已经包含查询和游标位置。但是您可以简单地在查询末尾添加附加条件,或强制使用索引。
-
用两个 $match 元素定义一个聚合管道是可行的。您收到什么错误消息?
-
@Pascal Bugnion 认真的吗?那我一定是做错了什么。我很快会再试一次。这会使用索引进行第一个查询吗?还是只是合并查询并使用基本游标?我使用的是 MongoDB
2.4,也许这两个 $matches 需要3.0? -
如果可以,它将使用索引。如果您将 { explain : true } 作为第二个参数传递给聚合调用,它将返回它将如何进行查询,而不是实际执行查询。您会发现,对于每个州,都有一个包含“光标”信息的“计划”字段。
-
也就是说,我认为您假设 MongoDB 引擎不如实际聪明。如果您将查询传递给
find,其中一些字段有索引而其他字段没有,它将首先使用适当的索引进行子选择,然后对剩余的文档进行全面搜索。
标签: mongodb indexing cursor aggregation-framework