Python 使用'进行批量插入$addToSet';要添加一组对象,请创建嵌套的字典数组,而不是字典数组
我正在尝试使用PyMongo将数据批量上传到mongoDB 我的目标如下:Python 使用'进行批量插入$addToSet';要添加一组对象,请创建嵌套的字典数组,而不是字典数组,python,mongodb,pymongo,Python,Mongodb,Pymongo,我正在尝试使用PyMongo将数据批量上传到mongoDB 我的目标如下: 检查数据库中是否存在工作应用程序id 如果存在,将“tobeaded”数组中的唯一对象与mongoDB中的相应字段连接起来 如果它不存在,则创建一个“appl_id”为“working_appl_id”的记录,并设置“tobeaded”字典 例如。 将以下内容插入空数据库 Appl Id | First Name | Last Name | Ip Address | Ip Country 123 |
Appl Id | First Name | Last Name | Ip Address | Ip Country
123 | John | Johnson | x.x.x.x | USA
123 | Peter | Peterson | y.y.y.y | FRA
应该导致
{
'appl_id': 123,
'name':[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
],
'ip':[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
]
},
{
'appl_id': 123,
'name':[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'},
{'first':'Mayer', 'last':'Mayerson'}
],
'ip':[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'},
{'address': 'z.z.z.z', 'country': 'GER'}
]
},
{
'appl_id': 456,
'name': [
{'first':'Will', 'last':'Willson'},
],
'ip': [
{'address': 'x.x.x.x', 'country': 'USA'}
]
},
现在将以下内容添加到上述数据库中
Appl Id | First Name | Last Name | Ip Address | Ip Country
123 | Mayer | Mayerson | x.x.x.x | USA
123 | John | Johnson | z.z.z.z | GER
456 | Will | Willson | x.x.x.x | USA
应该导致
{
'appl_id': 123,
'name':[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
],
'ip':[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
]
},
{
'appl_id': 123,
'name':[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'},
{'first':'Mayer', 'last':'Mayerson'}
],
'ip':[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'},
{'address': 'z.z.z.z', 'country': 'GER'}
]
},
{
'appl_id': 456,
'name': [
{'first':'Will', 'last':'Willson'},
],
'ip': [
{'address': 'x.x.x.x', 'country': 'USA'}
]
},
我的代码如下所示
db = client['some_db']
col = db['some_collection']
bulk = col.initialize_unordered_bulk_op()
working_appl_id=123
toBeAdded={
"name":[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
]
"ip":[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
]
}
bulk.find({"appl_id": working_appl_id}).upsert() \
.update(
{
'$addToSet': toBeAdded,
'$setOnInsert': {
"appl_id": working_appl_id,
},
}
)
res = bulk.execute()
我的代码的输出不是期望的输出。我的代码的输出是这样的
{
'appl_id': 123,
'name': [
[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
],
[
{'first':'Mayer', 'last':'Mayerson'}
{'first':'John', 'last':'Johnson'},
],
],
'ip': [
[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
],
[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'z.z.z.z', 'country': 'GER'}
]
]
},
{
'appl_id': 456,
'name': [
{'first':'Will', 'last':'Willson'},
]
'ip': [
{'address': 'x.x.x.x', 'country': 'USA'}
]
},
我得到了一个带字典的数组,而不是一个带唯一字典的数组。(参见“名称”或“ip”键)
如何在不创建数组的情况下删除执行upsert?
TOBEADED
变量由要插入的对象数组组成,当您尝试通过$addToSet
或$push
更新方法插入数组时,它将插入整个数组本身,而不是该数组中的对象
必须循环遍历数组中的对象,并通过单独的更新命令插入每个元素。或者您可以使用$each
操作符让MongoDB为您完成这项工作
下面是您的代码应该是什么:
from pymongo import MongoClient
client = MongoClient()
db = client['temp']
col = db['answer_temp']
bulk = col.initialize_unordered_bulk_op()
working_appl_id=123
toBeAdded={
"name":[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
],
"ip":[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
]
}
bulk.find({"appl_id": working_appl_id}).upsert() \
.update(
{
'$addToSet': {
"name": { "$each": toBeAdded["name"] },
"ip": { "$each": toBeAdded["ip"] }
},
'$setOnInsert': {
"appl_id": working_appl_id,
},
}
)
res = bulk.execute()
注意:我还没有在本地测试过我的代码,所以如果出现问题一定要告诉我
另外,initialize\u unordered\u bulk\u op
也不推荐使用。您可以将其重新写入以下内容:
from pymongo import MongoClient
from pymongo.errors import BulkWriteError
from pymongo import UpdateOne
client = MongoClient()
db = client['temp']
col = db['answer_temp']
# bulk = col.bulk_write()
working_appl_id=123
toBeAdded={
"name":[
{'first':'John', 'last':'Johnson'},
{'first':'Peter', 'last':'Peterson'}
],
"ip":[
{'address': 'x.x.x.x', 'country': 'USA'},
{'address': 'y.y.y.y', 'country': 'FRA'}
]
}
requests = []
requests.append(
UpdateOne(
filter={
"appl_id": working_appl_id
},
update={
'$addToSet': {
"name": { "$each": toBeAdded["name"] },
"ip": { "$each": toBeAdded["ip"] }
},
'$setOnInsert': {
"appl_id": working_appl_id,
},
},
upsert=True
)
)
try:
col.bulk_write(requests, ordered=False)
except BulkWriteError as bwe:
print(bwe.details)
你的问题是什么?@D.SM对不起,我不习惯在这里发帖。谢谢你的反馈。我已经更新了帖子。我添加了代码的输出以及问题。这样更好吗?我想您需要的是中描述的,即使用$each.@D.SM谢谢您的帮助。文档确实很有用,尽管我尝试了广泛的搜索,但我以前找不到它。感谢您的回复。你所做的改变非常有效。我感谢你的帮助