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 } } )