我有一份格式如下的文件:
{
"f1": "v1",
"f2": {
"id": 1,
"sub": "subv",
"updatedAt": 123
}
}
我有另一个来源,给我一个inputf2
个物体.
Input:
{"id": 1,"sub": "newsubv","updatedAt": 100}
因为Output<;123.id=1将不会被更新.Output:
{
"f1": "v1",
"f2": {"id": 1,"sub": "subv","updatedAt": 123}
}
Input:
{"id": 1,"sub": "newsubv","updatedAt": 150}
因为150>;123.id=1将被更新.Output:
{
"f1": "v1",
"f2": {"id": 1,"sub": "newsubv","updatedAt": 150}
}
Input:
{"id": 2,"sub": "newsubv","updatedAt": 100}
因为在db中找不到输入id=2.不管updatedAt
是多少,它都会被插入.Output:
{
"f1": "v1",
"f2": {"id": 1,"sub": "subv","updatedAt": 123}
},
{
"f1": "v1",
"f2": {"id": 2,"sub": "newsubv","updatedAt": 100}
}
我try 了两种类型的更新,更新文档或更新聚合管道,但似乎其中任何一种都符合我的要求.
With update document
我可以使用$setOnInsert
,但不能将f2
设置为f2.updatedAt < inputf2.updatedAt
条件:
db.collection.update({
"f2.id": "1"
},
{
"$set": {
// Can not check updatedAt = 100 < 123 and then do nothing
"f2": {
"id": 1
"sub": "newsubv",
"updatedAt": 100
}
},
"$setOnInsert": {
"f1": "v1"
}
},
{"upsert": true});
With update aggregation pipeline
通过将f2
克隆到新字段oldf2
,然后应用条件并删除oldf2
,我可以用f2.updatedAt < inputf2.updatedAt
条件更新f2
,但有点棘手.但在聚合中,没有$setOnItem
函数:
db.test.updateOne(
{"f2.id": 1},
[
{$set: {"oldf2": "$f2"}},
{
$set: {
"f2": {
$cond: [{$lt: ["$f2.updatedAt", 100]}, {
"id": 1,
"sub": "newsubv",
"updatedAt": 100
}, "$oldf2"]
}
}
},
{$set: {"oldf2": "$$REMOVE"}},
// How to apply something like $setOnInsert function?
],
{"upsert":true})
我必须使用updateOne
,因为有一个f2
项的列表,我想在bulkWrite
中批量更新这些项.
Noted:f2.id
是一个独特的Collection 领域
有人能帮我写下这个逻辑的查询吗?非常感谢你们.