从http://docs.mongodb.org/manual/core/indexes/#multikey-indexes,可以使用多键索引在数组字段上创建索引。http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes列出了如何在聚合框架中使用索引的一些方法。但是,有时我可能需要对$unwind
数组字段执行$group
. 我的问题是,多键索引(或使用此类数组字段的任何索引)一旦在管道中间进行操作,是否仍然可以使用?
2 回答
通常,只有可以展平为普通查询($match
、$limit
、$sort
和$skip
)的管道运算符才能使用集合上的索引。这是$geoNear
2.4 中添加的运算符必须位于管道开头的原因之一。
$project
一旦您使用,$group
或索引对文档进行变异,$unwind
则该索引不再有效/可用。
如果您在数组字段上有索引,您仍然可以在 之前使用它$unwind
来加快选择要流水线的文档,然后再进一步细化所选文档$match
。
考虑以下文件:
{ tags: [ 'cat', 'bird', 'blue' ] }
上的索引tags
。
如果您只想对以开头的标签进行分组,b
则可以执行如下聚合:
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }
第一个$match
使用 上的索引进行粗粒度匹配tags
。
之后的第二个匹配项$unwind
将无法使用索引(上面的文档现在是 3 个文档),但可以评估每个文档以过滤掉创建的额外文档(删除 { tags : 'cat' } from这个例子)。
HTH - 抢。
嗯@Rob 确实给出了正确的答案,但我知道他是如何引导你走错路的:
如果您在数组字段上有索引,您仍然可以在 $unwind 之前和之后使用它来加快选择要流水线的文档,然后进一步细化所选文档。
基本上他给出的例子:
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }
过去不会使用多键索引$unwind
。因此,它将能够搜索所有具有标签名称的 ROOT 文档,b
但是,它将无法使用索引$unwind
在第二个中过滤掉子文档。$match
$match
仅适用于突变之前的索引。
所以基本上一旦你改变了文档并将其加载到管道上,目前几乎不可能使用索引。