你最好的选择,尤其是如果你的应用程序还没有准备好发布,那就是推迟到 MongoDB 3.2 进行部署,或者至少在此期间开始使用候选发布版本。主要原因是“投影”$slice 不适用于聚合框架,其他形式的数组匹配投影也不适用。但这已在即将发布的版本中得到解决。
这将为您提供一些新的运算符,例如 $slice 甚至是 $arrayElemAt,它们可用于按聚合管道中的位置来寻址数组元素。
要么:
db.getCollection('anothertest').aggregate([
{ "$project": {
"_id": 0,
"a": { "$slice": ["$a",0,1] }
}}
])
返回熟悉的:
{ "a" : [ 4 ] }
或者:
db.getCollection('anothertest').aggregate([
{ "$project": {
"_id": 0,
"a": { "$arrayElemAt": ["$a", 0] }
}}
])
这只是元素而不是数组:
{ "a" : 4 }
在该版本以候选版本形式以外的形式可用之前,当前可用的运算符使数组的“第一个”元素变得非常容易:
db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
{ "$group": {
"_id": "$_id",
"a": { "$first": "$a" }
}}
])
通过在$unwind 之后使用$first 运算符。但是获取另一个索引位置变得非常迭代:
db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
// Keeps the first element
{ "$group": {
"_id": "$_id",
"first": { "$first": "$a" },
"a": { "$push": "$a" }
}},
{ "$unwind": "$a" },
// Removes the first element
{ "$redact": {
"$cond": {
"if": { "$ne": [ "$first", "$a" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
// Top is now the second element
{ "$group": {
"_id": "$_id",
"second": { "$first": "$a" }
}}
])
等等,还有很多处理来改变它以处理可能比您正在寻找的“第 n 个”元素更短的数组。如此“可能”,但丑陋且性能不佳。
还注意到“不是真的”与“索引位置”一起工作,并且纯粹是在值上匹配。所以重复值很容易被删除,除非每个数组元素有另一个唯一标识符可以使用。 Future $unwind 还具有投影数组索引的能力,这对于其他目的很方便,但其他运算符对于这种特定情况比该功能更有用。
因此,为了我的钱,我会等到您拥有能够将其集成到聚合管道中的功能,或者至少重新考虑您为什么认为您需要它并可能围绕它进行设计。