我有一些文档,它们代表用户的入职数据存储为嵌套对象:
{
"_id" : ObjectId("5c7eb0132e6f793bcc7f4bf7"),
"userName" : "sample_user_name",
"onBoarding" : {
"completed" : ISODate("2019-03-05T17:46:28.803Z"),
"stepId" : 8,
"started" : null
}
}
但是由于存在一个错误,我们错过了入职开始的日期,我想通过运行将“开始”的日期设置为与“完成”相同的更新操作来“检索”此信息。我有一个查询,例如:
db.getCollection('user').updateMany(
{
$and: [
{"onBoarding.started": {$exists: false}},
{"onBoarding.completed": {$exists: true}}
]},
{
$set: { "onBoarding.started": "$onBoarding.completed" }
})
但是,这实际上将“开始”设置为“ $ onBoarding”(作为字符串)。
{
"_id" : ObjectId("5c7eb0132e6f793bcc7f4bf7"),
"userName" : "sample_user_name",
"onBoarding" : {
"completed" : ISODate("2019-03-05T17:46:28.803Z"),
"stepId" : 8,
"started" : "$onBoarding"
}
}
我应该如何为mongo编写它以从“ onBoarding.completed”中获取一个值并将该值复制到“ onBoarding.started”中? 预期结果文档应如下所示:
{
"_id" : ObjectId("5c7eb0132e6f793bcc7f4bf7"),
"userName" : "sample_user_name",
"onBoarding" : {
"completed" : ISODate("2019-03-05T17:46:28.803Z"),
"stepId" : 8,
"started" : ISODate("2019-03-05T17:46:28.803Z")
}
}
答案 0 :(得分:1)
exists运算符检查字段的存在。如果字段的值为null
,查询仍将返回true(因为该字段仍然存在,因此只有其值为null)。
以下查询与此输入文档的行为有所不同:{ _id: 1, fld1: 123, fld2: null }
db.test.find( { fld2: { exists: false } } )
返回false
。db.test.find( { fld2: null } } )
返回true
。回到有问题的数据-以下查询/脚本将更新具有以下条件的所有文档:(“ onBoarding.started”为null
或存在) 和 (“ onBoarding.completed”字段存在并且不是null
)。
db.test.find( { $and: [ { $or: [ { "onBoarding.started": null }, { "onBoarding.started": { $exists: false } } ] }, { $and: [ { "onBoarding.completed": { $exists: true } }, { "onBoarding.completed": { $ne: null } } ] } ] } ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { "onBoarding.started" : doc.onBoarding.completed } } ) )
db.test.updateMany(
{ $and: [ { $or: [ { "onBoarding.started": null }, { "onBoarding.started": { $exists: false } } ] }, { $and: [ { "onBoarding.completed": { $exists: true } }, { "onBoarding.completed": { $ne: null } } ] } ] },
[
{ $addFields:
{ "onBoarding.started" : "$onBoarding.completed" }
}
]
)
答案 1 :(得分:0)
您需要使用聚合管道才能使用另一个字段的值:
db.user.updateMany(
{ <your query selector > },
[
{ $set: { onBoarding.started: "$onBoarding.completed" } },
]
)
请注意,这里的$ set指的是聚合管道阶段,而不是更新操作符$ set:https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/index.html#update-with-aggregation-pipeline