如何在使用MongoDB聚合框架展开数组后投影数组索引

9

当使用MongoDB聚合管道解开数组(http://docs.mongodb.org/manual/reference/operator/aggregation/unwind/#pipe._S_unwind)时,是否可以访问数组索引?

例如,假设我在集合“c”中解开此文档:

{_id: 1, elements: ["a", "b", "c"]}

然后进行这个操作:
db.c.aggregate([
 {$unwind: "$elements"}
])

将为文档返回一个游标:

[
 {_id: 1, elements: "a"},
 {_id: 1, elements: "b"},
 {_id: 1, elements: "c"}
]

我希望能够在展开操作之前确定“a”具有索引0,“b”具有索引1,并且“c”具有索引2在原始数组中。如何在展开操作中投影数组索引?
2个回答

15

最新发布的MongoDB 3.2支持展开数组索引。

与其在$unwind操作符中传递路径,你可以传递一个具有字段path和字段includeArrayIndex的对象,该对象将保存数组索引。

来自MongoDB官方文档

{
  $unwind:
  {
    path: <field path>,
    includeArrayIndex: <string>,
    preserveNullAndEmptyArrays: <boolean>
  }
}

在聚合操作中,是否有可能对其进行反向操作?或者,在MongoDB中无法实现数组投影,但是代码被接受。抱歉,我的意思是反转“unwind”。 - Tokenyet
@Tokenyet,简而言之:是的,这是可能的。例如,如果您展开了字段“elements”,那么可以像这样组合它:{ $group: { _id: '$_id', elements: { $push: '$elements' } } }。如果您能将其作为单独的问题提交(不仅仅是评论),那就太好了,这样我就可以在那里给出完整的答案。 - Maxim Georgievskiy

3

目前似乎无法使用聚合框架实现此功能。与此相关的有一个未解决的开放问题:https://jira.mongodb.org/browse/SERVER-4588

作为一种解决方法,你可以使用Map-reduce, 并将索引分配给每个数组元素。

var map = function(){
    for(var i=0;i<this.elements.length;i++){
    emit({"_id":this._id,"index":i},{"index":i,"value":this.elements[i]});
    }
}

谢谢!我之前的印象是不可能实现,因为我没有找到任何示例或者操作符来投影索引。但是我还没有找到这个问题报告。谢谢! - Roland Bouman
1
非常欢迎。一组运算符,$let$map的组合可以让我们接近项目操作的值,但由于它们的作用域限制,无法实现增量索引。 - BatScream
我知道使用map/reduce可以在map/reduce实现的限制范围内做任何事情。有一件事让我感到困惑,那就是如何确保map结果不会太大。关于手头的问题,我认为JIRA案例提出了一个合理的方法来投影索引。到目前为止,我在学习查询MongoDB方面遇到了相当陡峭的学习曲线。 - Roland Bouman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接