假设我有一个如下所示的文档:
{
"_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
"systemId" : "5124301",
"userId" : "9876543210",
"tempId" : "123456da87sdafasdf",
"updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
"receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}
现在我已经为文档分配了一个tempId
,有时该字段可能会过期,并且不存在于文档中。我想知道如果我正在使用不同的receivedAt
参数或任何其他参数更新文档,并且它没有tempId,则只为其分配tempId
,否则让tempId
保持原样。
如两个示例所示,要获得更新的文档,应该查询什么?
情况1:如果tempId
存在:
{
"_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
"systemId" : "5124301",
"userId" : "1234567890",
"tempId" : "123456da87sdafasdf",
"updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
"receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}
情况2:如果没有tempId
,并且在上面的行中生成为“13qeqrwrqwtqrfsdfweqr”,则需要使用生成的tempId
更新文档。
{
"_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
"systemId" : "5124301",
"userId" : "1234567890",
"tempId" : "13qeqrwrqwtqrfsdfweqr",
"updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
"receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}
查询将类似于以下内容:
findOneAndUpdate({
systemId: "5124301"
},
{
{
$set: {
userId: "1234567890",
receivedAt : ISODate("2022-04-10T23:15:08.145+0000"),
tempId: {
$exists: then leave it as is, else update it with 13qeqrwrqwtqrfsdfweqr
}
}
}
})
2条答案
按热度按时间kjthegm61#
使用聚合管道更新。使用
$cond
运算符检查tempId
是否不等于($ne
)undefined
。如果为true,则保留现有值
$tempId
。如果为false,则赋值:
"13qeqrwrqwtqrfsdfweqr"
.Demo @ Mongo Playground
4c8rllxm2#
我同意@Yong Shun的观点,使用聚合管道来描述转换是解决这个问题的正确方法。我在下面提供了一个替代语法,只是作为一般参考,尽管两者都能很好地满足问题中的要求。
主要是留下一个额外的答案,因为我很好奇 * 为什么 * 这个围绕
tempId
的工作流程存在。它们代表什么,为什么可以与userId
共存,以及为什么应用程序为这些写操作中的每一个生成新的写操作,即使一个写操作可能已经存在?有一件事需要注意,您可以为更新构建过滤 predicate ,以包含对tempId
的引用(也许只让应用程序在需要的时候生成一个新的)。但更重要的是,我怀疑tempId
的整个工作流程应该被简化,但这需要更具体的应用程序知识才能确定。关于替代语法,流水线的
tempId
部分可以简化为使用$ifNull
运算符:Full demo playground here .