我想在一个“目标”集合的每个文档中设置一个新字段的值,基于另一个“源”集合的文档中的一个字段的值。
目标集合的文档如下所示:
db.names:
{
"name" : "Larry",
"info" : {
"phone" : "5551212"
}
}
{
"name" : "Curly",
"info" : {
"phone" : "5551213"
}
}
{
"name" : "Moe",
"info" : {
"phone" : "5551234"
}
}第二个集合的文档如下所示(我希望将这个时区添加到目标集合中):
db.phones:
{
"phone" : "5551212",
"timezone" : "UTC-6"
}
{
"phone" : "5551213",
"timezone" : "UTC-7"
}
{
"phone" : "5551234",
"timezone" : "UTC-6"
}我希望第一个“目标”集合的文档看起来像这样:
db.names:
{
"name" : "Larry",
"info" : {
"phone" : "5551212",
"timezone" : "UTC-6"
}
}
{
"name" : "Curly",
"info" : {
"phone" : "5551213",
"timezone" : "UTC-7"
}
}
{
"name" : "Moe",
"info" : {
"phone" : "5551234",
"timezone" : "UTC-6"
}
}换句话说,我有一个包含时区的非常大的集合(电话)和一个不包含时区的非常大的集合(名称),我希望第一个集合包含这些时区,并使用两者中的电话号码作为键。
我已经在mongoShell中尝试过了,但没有成功:
list = db.names.aggregate([
{ $match: { } },
{ $lookup: {
from: "phones",
localField: "info.phone",
foreignField: "phone",
as: "zoneinfo"
}
}
]);
list.result.forEach(function(x) {
db.names.update({_id:x._id}, {$set:{'info.timezone':'zoneinfo.timezone'}});
});因此,链接时区的集合并将其添加到list,结果是,作为每个文档上的一个新字段(这是可行的)。然后,由于我们不能在aggregate中进行更新,因此迭代结果文档,添加一个新的永久字段info.timezone,该字段来自在前一个操作中添加的“临时”字段zoneinfo.timezone。
我在这里做错了什么?有没有其他更可取的方法?每个集合中有数千个文档,因此不希望手工操作。
发布于 2019-03-15 04:21:02
您需要记住的一件事是,$lookup将zoneInfo作为数组返回,因此为了使用该字段,您需要对其运行$unwind。然后,您可以简单地使用$addFields和$project重塑您的文档。尝试:
db.names.aggregate([
{
$lookup: {
from: "phones",
localField: "info.phone",
foreignField: "phone",
as: "phoneDetails"
}
},
{
$unwind: "$phoneDetails"
},
{
$addFields: {
"info.timezone": "$phoneDetails.timezone"
}
},
{
$project: {
phoneDetails: 0
}
}
])在最后一步中,如果您想要更新现有集合,则可以添加$out。
https://stackoverflow.com/questions/55170720
复制相似问题