在http://docs.mongodb.org/manual/core/indexes/#multikey-indexes中,可以使用多键索引在数组字段上创建索引。http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes列出了如何在聚合框架中使用索引的一些方法。但是,有时我可能需要对数组字段执行$unwind才能执行$group。我的问题是,多键索引(或任何使用这种数组字段的索引)在流水线中间被操作后还可以使用吗?
发布于 2013-03-25 11:19:54
通常,只有可以展开为普通查询的管道操作符($match、$limit、$sort和$skip)才能使用集合上的索引。这就是在2.4中添加的$geoNear运算符必须位于管道开头的原因之一。
一旦使用$project、$group或$unwind更改了文档,索引就不再有效/可用。
如果您有一个数组字段上的索引,您仍然可以在$unwind之前使用它来加快选择要流水线的文档的速度,然后使用第二个$match进一步优化所选文档。
考虑如下文档:
{ tags: [ 'cat', 'bird', 'blue' ] }并在tags上建立索引。
如果您只想对以b开头的标记进行分组,则可以执行如下聚合:
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }第一个$match使用tags上的索引进行粗粒度匹配。
标记之后的第二个匹配将不能使用索引(上面的文档现在是3个文档),但可以评估每个文档以过滤掉创建的额外文档(从示例中删除{ $unwind:'cat‘})。
HTH - Rob
发布于 2013-03-25 18:48:36
嗯,@Rob确实给出了正确的答案,但我知道他可能会把你引向错误的道路:
如果您在数组字段上有索引,您仍然可以在$unwind之前和之后使用它来加快选择要流水线的文档的速度,然后进一步优化所选的文档。
基本上他给出的例子是:
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }将不会使用超过$unwind的多键索引。因此,它将能够搜索标记名以b开头的所有根文档,但是,它将不能$unwind,然后使用索引在第二个$match中筛选出子文档。
$match将只在变异之前的索引上工作。
因此,一旦你改变了文档并将其加载到流水线上,现在就几乎不可能使用索引了。
https://stackoverflow.com/questions/15606963
复制相似问题