mongodb - 如何在 mongodb 中更新或插入嵌套文档到数组中

标签 mongodb mongodb-query pymongo

我在 mongodb 中很新,所以这是我的问题,我想要的是检查主文档是否存在,如果存在,检查嵌套文档是否存在,然后更新它,如果它不插入新文档。但是使用此代码,我只能更新现有的嵌套文档,但无法创建新文档。
我什至不知道是否正确使用这种方法,是否有效?

collection.find_one_and_update(
 {"_id:{"field1":val1,"field2":val2,"field3":val3,"field4":val4}},
 {"$set":{"elements.$[element].prop2":valToUpdate}},
 return_document=ReturnDocument.AFTER, 
 array_filters=[{"element.prop1":valToCheck}],
 upsert=True
)

在 mongo 语法中,我认为是这样的:
db.collection.findOneAndUpdate(
   {"_id:{"field1":val1,"field2":val2,"field3":val3,"field4":val4}},
   {"$set":{"elements.$[element].prop2":valToUpdate}},
   { arrayFilters: [ {"element.prop1":valToCheck} ] }
)


我可以使用像这样的单个函数来完成整个过程(检查主文档和嵌套文档是否存在以及它是否更新,否则创建一个新的)?

我想如何更改文档的示例:

在执行方法之前
{
   "_id":{"name":"Storename","location":"somewhere","phone":46284723},
   "books":
      [
         {"name":"somebook","price":{"$numberDouble":"34"}}
      ]
}

执行后如果有嵌套文档
{
   "_id":{"name":"Storename","location":"somewhere","phone":46284723},
   "books":
      [
         {"name":"somebook","price":{"$numberDouble":"55"}},
      ]
}

执行后如果没有嵌套文档
{
   "_id":{"name":"Storename","location":"somewhere","phone":46284723},
   "books":
      [
         {"name":"somebook","price":{"$numberDouble":"34"}},

         {"name":"someOTHERbook","price":{"$numberDouble":"45"}}
      ]
}

最佳答案

那是因为 upsert似乎不适用于 $运算符,通常 upsert 也是在文档级别,但不应该用于像这种情况下插入数组的缺失元素。由于实际文档存在于 DB 中,因此会出现重复的错误 _id .

如果您想在一次数据库调用中执行此操作,那么以下查询应该适用于您的场景,因为在任何给定情况下,只有一个 updateOne应该更新数组:

Mongo 查询:

db.yourCollectionName.bulkWrite([
    {
        updateOne: {
            filter: {
                "_id": {
                    "name": "Storename",
                    "location": "somewhere",
                    "phone": 46284723
                }, 'books.name': 'somebook'
            }, update: {
                $set: { "books.$.price": 100 }
            }
        }
    },
    {
        updateOne: {
            filter: {
                "_id": {
                    "name": "Storename",
                    "location": "somewhere",
                    "phone": 46284723,
                }
            }, update: {
                $addToSet: { 'books': { 'name': 'somebook', "price": 100 } }
            }
       }
 }])

Python 代码:
import pymongo
from pymongo import UpdateOne

bulkArr = [
    UpdateOne({
        "_id": {
            "name": "Storename",
            "location": "somewhere",
            "phone": 46284723
        }, 'books.name': 'somebook'
    }, { '$set': { "books.$.price": 100 } }),
    UpdateOne({
        "_id": {
            "name": "Storename",
            "location": "somewhere",
            "phone": 46284723,
        }
    }, {
        $addToSet: { 'books': { 'name': 'somebook', "price": 100 } }
       })
   ]

db.yourCollectionName.bulk_write(bulkArr)

PyMongo 引用:请引用此链接以转换此查询。 PyMongo-bulk_write

关于mongodb - 如何在 mongodb 中更新或插入嵌套文档到数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59692316/

相关文章:

MongoDB : use $ positional operator for querying

node.js - 类型对象的 sailsjs 模型属性,可能吗?

node.js - 如果我没有回调函数,Mongoose 不会更新我的文档

mongodb - 如何检查一个集合中 _id 的一部分是否出现在另一个集合中

mongodb - pymongo db.collection_names() 返回空列表

mongodb - 将 msg 对象插入 mongodb (node-red)?

javascript - 在一个 Mongoskin 查询中推送多个数组

Mongodb - 使用聚合框架对多个字段进行分组

python - MongoDB 和 PyMongo - 如何在单个文档字段中连接字符串

mongodb - PyMongo 事务错误 :Transaction numbers are only allowed on a replica set member or mongos