你能否在Mongo中使用$push进行前置而非后置操作?

48

当我使用mongo $push时,我希望将推送添加到集合的开头而不是结尾。

是否有可能进行原子推送更新,将元素添加为第一个而不是最后一个?


2014年更新: 是可以的


1
请参见http://stackoverflow.com/questions/10094573/use-mongodb-array-as-stack#comment12929388_10094573。 - Chris Shain
2
可能是重复的问题:如何在MongoDB中将值添加到数组的顶部? - Dan Dascalescu
3个回答

36

从MongoDB v2.5.3开始,有一个新的$position运算符,您可以将其与$each运算符一起作为$push查询的一部分包含在内,以指定要插入值的数组位置。

以下是文档页面上添加元素20和30到索引为2的数组的示例:

db.students.update( { _id: 1 },
                    { $push: { scores: {
                                         $each: [ 20, 30 ],
                                         $position: 2
                                       }
                             }
                    }
                  )

参考文档:http://docs.mongodb.org/master/reference/operator/update/position/#up._S_position


的确,一旦他们推出2.6稳定版本,这将是很好的。 - lostintranslation
5
"$push - $each - $position: 0" 的语法不太方便。请通过投票来帮助 实现 $unshift - Dan Dascalescu
只对更新有效,对于向数组中添加新项无效。 - backdesk
1
当我向数组中添加一个单一值时,我是否必须使用 $each - Константин Ван
1
@КонстантинВан:“要使用$position修饰符,必须与$each修饰符一起出现。” 来源:https://docs.mongodb.com/manual/reference/operator/update/position/ - jeff musk
在某种编程语言中,这种方法是否比从Mongo检索数组、手动插入数组并完全替换/更新Mongo数组的方式更快? - Happy John

30

使用$set和负索引进行前置插入,已在Mongo v2.2中测试:

> db.test.insert({'array': [4, 5, 6]})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"),
  "array" : [ 4, 5, 6 ] }

//prepend 3
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     3}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 3, 4, 5, 6 ] }

//prepend 2
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     2}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 2, 3, 4, 5, 6 ] }

//prepend 1
> db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     1}})
> db.test.find()
{ "_id" : ObjectId("513ad0f8afdfe1e6736e49eb"), 
  "array" : [ 1, 2, 3, 4, 5, 6 ] }

有没有一种方法可以在数组的开头设置多个值? - Modi
很好的解决方法。看起来Mongo 2.6(稳定版)将包括一个非解决方法。 - lostintranslation
你如何原子性地一次性unshift多个元素? - Dan Dascalescu
1
顺便问一下,这个功能有文档记录吗? - Marwin
5
这还有效吗?我一直收到“MongoError:无法在元素中创建字段‘-1’”。 - koolaang

6
几天前也有一个类似的问题被提出。不幸的是,简短的答案是“不行”,但这个功能有一个公开的请求。
https://jira.mongodb.org/browse/SERVER-2191 -"$push()到数组前面"
在其他线程中还有一些更多信息以及可能的解决方法: “使用MongoDB数组作为堆栈” -使用MongoDB数组作为堆栈 希望以上内容对您有所帮助,并帮助您找到可接受的解决方案。

啊哈。看起来Chris Shain比我更快地完成了!在我发布之前我没有看到这个评论。 - Marc
@Monkey:自从v2.5.3版本起,你可以使用$push - $each - $position: 0的语法了。能否请你更新一下被接受的答案?同时,由于这种语法很奇怪,请通过在此问题上投票来帮助实现$unshift(https://jira.mongodb.org/browse/SERVER-19974)。 - Dan Dascalescu

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