mongo可以插入数组数据吗?
我有这样的mongo文件。
{ "_id" : ObjectId("50b429ba0e27b508d854483e"), "array" : [ { "id" : "1", "letter" : "a" }, { "id" : "2", "letter" : "b" } ], "tester" : "tom" }
我希望能够插入和更新一个单一的mongo命令的array
,而不是在find()
使用条件,然后根据对象的存在运行insert()
和update()
。
id
是我想成为select器的项目。 所以如果我用这个更新数组:
{ "id" : "2", "letter" : "c" }
我必须使用$set
语句
db.soup.update({ "tester":"tom", 'array.id': '2' }, { $set: { 'array.$.letter': 'c' } })
如果我想插入一个新的对象到数组中
{ "id" : "3", "letter" : "d" }
我必须使用$push
语句
db.soup.update({ "tester":"tom" }, { $push: { 'array': { "id": "3", "letter": "d" } } })
我需要一个数组项目的upsert。
我是否必须以编程方式执行此操作,还是可以使用单个mongo调用执行此操作?
我不知道在MongoDB 2.2中插入一个embedded式数组的选项,因此您可能必须在应用程序代码中处理这个选项。
假设您想将embedded式数组视为虚拟集合,您可能需要考虑将数组build模为单独的集合。
不能根据embedded数组中的字段值进行upsert,但是如果已经存在,则可以使用$addToSet
插入embedded的文档:
db.soup.update({ "tester":"tom" }, { $addToSet: { 'array': { "id": "3", "letter": "d" } } })
这并不符合数组元素的id
匹配的确切用例,但是如果您知道预期的当前值,则可能会有用。
我自己也遇到了这个问题。 我无法find一个通话解决scheme,但是我发现了一个双向通话解决scheme, 当你在数组元素中有一个唯一的值时,这个解决scheme就可以工作。 首先使用$pull
命令,从数组中删除元素,然后使用$push
。
db.soup.update({ "tester":"tom" }, { $pull: { 'array': { "id": "3" } } }) db.soup.update({ "tester":"tom" }, { $push: { 'array': { "id": "3", "letter": "d" } } })
这应该在文档不存在,文档存在但数组中的条目不存在以及条目存在时起作用。
同样,只有当你有一些东西,比如这个例子中的id
字段,这个字段在数组元素中应该是唯一的。
在某些情况下,如果可以重构文档以使用对象而不是数组,则可以实现embedded文档集的高位。 我只是在另一个问题上回答了这个问题,但为了方便起见,我们将在此进行调整
一个示例文件将是
{ tester: 'tom', items: { '1': 'a', '2': 'b' } }
要插入id
3和值'c'的项目,你会这样做
db.coll.update( { tester: 'tom' }, { $set: { 'items.3': 'c' } } )
一个缺点是查询字段名称(使用$exists
查询运算符)需要扫描。 您可以通过添加一个额外的数组字段来解决这个问题。 该字段可以正常索引和查询。 Upserts成为
db.coll.update( { tester: 'tom' }, { $set: { 'items.3': 'c' }, $addToSet: { itemNames: 3 } } )
(请记住$addToSet
是O(n)。)当删除一个属性时,你也必须从数组中取出它。
db.widgets.update( { tester: 'tom' }, { $unset: { 'items.3': true }, $pull: { itemNames: 3 } } )