假设我有以下文档。
[
{
"username": "admin",
"accessControl": [
{
"methods": ["GET", "PUT"],
"items": ["A", "B"]
}
{
"methods": ["GET", "PUT", "CREATE"],
"items": ["C"]
}
]
}, {
"username": "user_1",
"accessControl": [
{
"methods": ["GET", "PUT"],
"items": ["A"]
}
]
}, {
"username": "user_2"
}
]
我需要在文档中插入以下内容。
{
"accessControl": [{
"methods": ["GET", "PUT"],
"items": ["B"]
}]
}
根据当前结构,需要将插入的部分合并到docs中。因此,如果accessControl
不存在,则需要使用插入的项创建;
如果存在accessControl
数组且包含"methods": ["GET", "PUT"]
的对象,则需要将项"B"
推入对象的"items"
数组中。
如果存在accessControl
数组,但不包含"methods": ["GET", "PUT"]
的对象,则需要插入accessControl
{ "methods": ["GET", "PUT"], "items": ["B"] }
以后我可以拥有以下文档结构。
[
{
"username": "admin",
"accessControl": [
{
"methods": ["GET", "PUT"],
"items": ["A", "B"] //nothing inserted here since "B" is already present
}, {
"methods": ["GET", "PUT", "CREATE"],
"items": ["C"]
}
]
}, {
"username": "user_1",
"accessControl": [
{
"methods": ["GET", "PUT"],
"items": ["A", "B"] //item "B" has inserted here
}
]
}, {
"username": "user_2",
"accessControl": [
{
"methods": ["GET", "PUT"],
"items": ["B"] // item "B" is inserted along with the whole "accessControl"
}
]
}
]
答案 0 :(得分:1)
我没有看到如何在单个数据库查询中实现此目的。
我认为你需要先更新那些"方法"项目"匹配"。
let data = { "methods" : [ "GET", "PUT" ], "items" : [ "B" ] };
db.collection.updateMany(
{ "accessControl.methods": { "$all": [ "GET", "PUT" ] } },
{ "$addToSet": {
"accessControl.$.items": {"$each": data.items }
}}
)
然后更新"方法"的所有文件。字段不存在或与输入数据不匹配。
db.collection.updateMany(
{ "accessControl.methods": {
"$not": { "$all": [ "GET", "PUT" ] }
}},
{ "$push": { "accessControl.items": data } }
);
答案 1 :(得分:1)
我建议您考虑更改数据库结构。如果accesscontrol数组每个项目有一个文档,并且该对象允许使用一组方法,则此类更新会更容易。
所以你的收藏会是这样的:
[
{
"username": "admin",
"accessControl": [
{
"item" : "A",
"methods": ["GET", "PUT"],
},
{
"item" : "B",
"methods": ["GET", "PUT"]
},
{
"item": "C",
"methods": ["GET", "PUT", "CREATE"],
}
]
},
{
"username": "user_1",
"accessControl": [
{
"item": "A",
"methods": ["GET", "PUT"]
}
]
},
{
"username": "user_2"
}
]
您可以使用以下查询更新它:
db.collection.update(
{"accessControl.item" : {$ne: "B"}},
{$push: {"accessControl" : {"item" : "B"}}},
{multi: true}
);
db.collection.update(
{"accessControl.item" : "B"},
{$addToSet: { "accessControl.$.methods" : {$each: ["GET", "PUT"]} } },
{multi: true}
);
保留这样的数据:
[
{
"username" : "admin",
"accessControl" : [
{
"item" : "A",
"methods" : ["GET", "PUT"]
},
{
"item" : "B",
"methods" : ["GET", "PUT"]
},
{
"item" : "C",
"methods" : ["GET", "PUT", "CREATE"]
}
]
},
{
"username" : "user_1",
"accessControl" : [
{
"item" : "A",
"methods" : ["GET", "PUT"]
},
{
"item" : "B",
"methods" : ["GET", "PUT"]
}
]
},
{
"username" : "user_2",
"accessControl" : [
{
"item" : "B",
"methods" : ["GET", "PUT"]
}
]
}
]
注意: