gpt4 book ai didi

python - MongoDB 中的位置更新

转载 作者:可可西里 更新时间:2023-11-01 09:51:12 25 4
gpt4 key购买 nike

我正在尝试更新 MongoDB 中的子文档数组。我知道位置运算符 $ 不支持单个查询中的多个更新。

示例文档:

{
"_id": ObjectId("559a6c281816ba598cdf96cd"),
"collections": [
{
"id": 12,
"name": "a"
},
{
"id": 12,
"name": "b"
}
]
}

我需要用一个额外的字段 "price": 12 来更新 id : 12 子文档。我尝试了以下查询,但匹配的同一子文档正在更新,因此我添加了一个额外的条件 "price": {$exists : false} 并且还尝试了 "price": {$ne : 12}。当我添加 "price": {$exists : false} 时,没有返回任何文档。我正在使用 PyMongo 和 python 。那么我是否需要在python代码中执行更新并更新文档。有什么解决方法吗?

尝试查询:

db.scratch.update({ "collections.id" : 12 } , {"$set" : {"collections.$.price" : 12 }})

尝试使用上述 price : falseprice: {$exists : false} 的组合,但它们也不起作用。但我不断收到一份文件已更新的消息。我在我的 mongo shell 中使用 mongo-hacker。

我正在构建一个迁移工具,其中所有客户信息都显示为一个文档。

{
"_id": ObjectId("559a2d9bfffe043444c72889"),
"age": NumberLong("23"),
"customer_address": [
{
"type": "Work",
"verified": true,
"address": "1A NY"
}
],
"customer_id": NumberLong("3"),
"customer_orders": [
{
"order_date": ISODate("2015-01-01T00:12:01Z"),
"order_id": NumberLong("2"),
"product_id": NumberLong("234")
},
{
"order_date": ISODate("2015-12-01T00:00:00Z"),
"order_id": NumberLong("3"),
"product_id": NumberLong("245")
},
{
"order_date": ISODate("2015-12-21T00:00:00Z"),
"order_id": NumberLong("4"),
"product_id": NumberLong("267")
},
{
"order_id": NumberLong("5"),
"order_date": ISODate("2015-12-29T00:00:00Z"),
"product_id": NumberLong("289")
},
{
"order_id": NumberLong("9"),
"order_date": ISODate("2015-02-01T00:12:05Z"),
"product_id": NumberLong("234")
}
]
}

我从客户表中获取基本信息,从客户地址表中获取地址,从另一个通过 MySQL 中的外键引用关联的表中获取产品日志。现在我想用正确的名称和价格更新产品 ID,这样我就可以了解客户,而不是通过查询来获取产品 ID 的相应价格,而且由于

中不存在连接
{
"_id": ObjectId("559a2d9bfffe043444c72889"),
"age": NumberLong("23"),
"customer_address": [
{
"type": "Work",
"verified": true,
"address": "1A NY"
}
],
"customer_id": NumberLong("3"),
"customer_orders": [
{
"name": "Brush",
"order_date": ISODate("2015-01-01T00:12:01Z"),
"order_id": NumberLong("2"),
"product_id": NumberLong("234"),
"price": 12
},
{
"order_date": ISODate("2015-12-01T00:00:00Z"),
"order_id": NumberLong("3"),
"product_id": NumberLong("245")
},
{
"order_date": ISODate("2015-12-21T00:00:00Z"),
"order_id": NumberLong("4"),
"product_id": NumberLong("267")
},
{
"order_id": NumberLong("5"),
"order_date": ISODate("2015-12-29T00:00:00Z"),
"product_id": NumberLong("289")
},
{
"name": "Brush",
"order_id": NumberLong("9"),
"order_date": ISODate("2015-02-01T00:12:05Z"),
"product_id": NumberLong("234"),
"price": 12
}
]
}

尝试查询:

db.customer.update({"customer_orders.product_id" : 234 , "customer_orders.name" : {$exists : false}}, {"$set" : {"customer_orders.$.name" : "Brush", "customer_orders.$.price" : 12} } )

返回 0 个更新的文档。

db.customer.update({"customer_orders.product_id" : 234 , "customer_orders.name" : {$exists : true}}, {"$set" : {"customer_orders.$.name" : "Brush", "customer_orders.$.price" : 12} } )

返回 1 个文档已更新,但即使在顺序执行同一命令后,也只有第一个字段得到更新。那么是否有解决方法或者我是否需要在 Python 客户端中进行更新?

最佳答案

除了阅读文档以找出有多少数组元素并通过索引(或不同的“id”值)更新它们之外,这真的没什么用,但阅读之外并不重要首先是对象。

以最安全的方式,不要更改整个文档并将其“保存”回去,而是对每个数组元素执行更新:

id = ObjectId("559a2d9bfffe043444c72889")
doc = coll.find_one({ "_id": id })

for idx, el in enumerate(doc["customer_orders"]):
if ( el["product_id"] == 234 ):
update = { "$set": {} }
update["$set"]["customer_orders."+str(idx)+".price"] = 12
update["$set"]["customer_orders."+str(idx)+".name"] = "Brush"
coll.update({ "_id": id },update)

您可以通过批量操作提高效率:

id = ObjectId("559a2d9bfffe043444c72889")
doc = coll.find_one({ "_id": id })
bulk = coll.initialize_ordered_bulk_op()

for idx, el in enumerate(doc["customer_orders"]):
if ( el["product_id"] == 234 ):
update = { "$set": {} }
update["$set"]["customer_orders."+str(idx)+".price"] = 12
update["$set"]["customer_orders."+str(idx)+".name"] = "Brush"
bulk.find({ "_id": id }).update(update)

bulk.execute()

至少一次将所有更新发送到服务器

但一般来说,您需要通过其他唯一标识符的索引来识别“确切”元素,以便发送正确的更新位置。

尝试类似的东西

{ "customer_orders.price": { "$exists": False } }

{ "customer_orders.product_id": 234 }

会遇到以下问题:

  • 一般来说,在这两种情况下它都会匹配多个东西
  • 对于 $exists,位置 $ 匹配操作是 Not Acceptable ,只有精确值匹配才会产生更新索引。

因此从文档本身读取“准确”的 id 或位置索引,然后处理更新。

关于python - MongoDB 中的位置更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31245572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com