MongoDB 推送到嵌套数组或插入新文档
MongoDB push to nested array or insert new document
我正在为 Mongo (pymongo) 使用 python 的库,我的文档如下所示:
{"vendor_id": 12, "title": "xyz", "price": 1499.0, "price_history": [{"date": "2019-12-01", "price": 1890.0}]}
如果存在 id=12 的文档,我想将新的价格对象推送到 "price_history" 数组。如果没有,我会创建一个看起来与粘贴代码相同的新文档。
这看起来很简单,但我检查了多个 Whosebug 主题和 mongodb 文档,但无法理解:/
我想出了代码:
db.holidays.update_one(
{"vendor_id": t["vendor_id"]},
{"$push": {"price_history": t["price_history"][0]}},
upsert=True
)
但是当找不到文档时,它只插入 vendor_id 而不是整个文档。
有什么建议吗?
感谢您花时间解决我的问题。
将记录提取到字典中并使用标准 python 操作。如果您使用 find_one()
并且没有匹配,它将 return None
from pymongo import MongoClient
from bson.json_util import dumps
db = MongoClient()["testdatabase"]
# Data setup
db.testcollection.delete_many({})
template = {"vendor_id": 12, "title": "xyz", "price": 1499.0, "price_history": []}
data_setup = {"vendor_id": 12, "title": "xyz", "price": 1499.0,
"price_history": [{"date": "2019-12-01", "price": 1890.0}]}
new_price = {"date": "2019-12-02", "price": 2000.0}
# Comment the next line out to see what happens if the record isn't present
db.testcollection.insert_one(data_setup)
record = db.testcollection.find_one({"vendor_id": 12})
if record is None:
record = template
record['price_history'].append(new_price)
db.testcollection.replace_one({"vendor_id": 12}, record, upsert=True)
# Pretty up the record output
print(dumps(db.testcollection.find_one({}, {'_id': 0}), indent=4))
给出:
{
"vendor_id": 12,
"title": "xyz",
"price": 1499.0,
"price_history": [
{
"date": "2019-12-01",
"price": 1890.0
},
{
"date": "2019-12-02",
"price": 2000.0
}
]
}
$setOnInsert
救援:
db.holidays.update(
{ "vendor_id": t["vendor_id" }, // Query parameter
,{ // Update document
"$push": {"price_history": t["price_history"][0]},
"$setOnInsert": { everything else you want insert besides the push and the vendor_id
}
,{ upsert: true } // Options
)
我正在为 Mongo (pymongo) 使用 python 的库,我的文档如下所示:
{"vendor_id": 12, "title": "xyz", "price": 1499.0, "price_history": [{"date": "2019-12-01", "price": 1890.0}]}
如果存在 id=12 的文档,我想将新的价格对象推送到 "price_history" 数组。如果没有,我会创建一个看起来与粘贴代码相同的新文档。
这看起来很简单,但我检查了多个 Whosebug 主题和 mongodb 文档,但无法理解:/
我想出了代码:
db.holidays.update_one(
{"vendor_id": t["vendor_id"]},
{"$push": {"price_history": t["price_history"][0]}},
upsert=True
)
但是当找不到文档时,它只插入 vendor_id 而不是整个文档。
有什么建议吗? 感谢您花时间解决我的问题。
将记录提取到字典中并使用标准 python 操作。如果您使用 find_one()
并且没有匹配,它将 return None
from pymongo import MongoClient
from bson.json_util import dumps
db = MongoClient()["testdatabase"]
# Data setup
db.testcollection.delete_many({})
template = {"vendor_id": 12, "title": "xyz", "price": 1499.0, "price_history": []}
data_setup = {"vendor_id": 12, "title": "xyz", "price": 1499.0,
"price_history": [{"date": "2019-12-01", "price": 1890.0}]}
new_price = {"date": "2019-12-02", "price": 2000.0}
# Comment the next line out to see what happens if the record isn't present
db.testcollection.insert_one(data_setup)
record = db.testcollection.find_one({"vendor_id": 12})
if record is None:
record = template
record['price_history'].append(new_price)
db.testcollection.replace_one({"vendor_id": 12}, record, upsert=True)
# Pretty up the record output
print(dumps(db.testcollection.find_one({}, {'_id': 0}), indent=4))
给出:
{
"vendor_id": 12,
"title": "xyz",
"price": 1499.0,
"price_history": [
{
"date": "2019-12-01",
"price": 1890.0
},
{
"date": "2019-12-02",
"price": 2000.0
}
]
}
$setOnInsert
救援:
db.holidays.update(
{ "vendor_id": t["vendor_id" }, // Query parameter
,{ // Update document
"$push": {"price_history": t["price_history"][0]},
"$setOnInsert": { everything else you want insert besides the push and the vendor_id
}
,{ upsert: true } // Options
)