MongoDB$集合在一起
我想根据另一个“源”集合的文档中的字段值,在“目标”集合的每个文档中设置一个新字段的值 目标集合的文档如下所示: db.name:MongoDB$集合在一起,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我想根据另一个“源”集合的文档中的字段值,在“目标”集合的每个文档中设置一个新字段的值 目标集合的文档如下所示: db.name: { "name" : "Larry", "info" : { "phone" : "5551212" } } { "name" : "Curly", "info" : { "phone" : "5551213" } } { "name" : "Moe", "i
{
"name" : "Larry",
"info" : {
"phone" : "5551212"
}
}
{
"name" : "Curly",
"info" : {
"phone" : "5551213"
}
}
{
"name" : "Moe",
"info" : {
"phone" : "5551234"
}
}
{
"name" : "Larry",
"info" : {
"phone" : "5551212",
"timezone" : "UTC-6"
}
}
{
"name" : "Curly",
"info" : {
"phone" : "5551213",
"timezone" : "UTC-7"
}
}
{
"name" : "Moe",
"info" : {
"phone" : "5551234",
"timezone" : "UTC-6"
}
}
第二个集合的文档如下所示(我希望将此时区添加到目标集合):
db.phones:
{
"phone" : "5551212",
"timezone" : "UTC-6"
}
{
"phone" : "5551213",
"timezone" : "UTC-7"
}
{
"phone" : "5551234",
"timezone" : "UTC-6"
}
我希望第一个“目的地”集合的文档最终看起来像这样:
db.name:
{
"name" : "Larry",
"info" : {
"phone" : "5551212"
}
}
{
"name" : "Curly",
"info" : {
"phone" : "5551213"
}
}
{
"name" : "Moe",
"info" : {
"phone" : "5551234"
}
}
{
"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'}});
});
因此,将时区集合链接起来,并将其添加到列表
,作为每个文档上的一个新字段(这非常有效)。然后,由于我们无法在聚合中执行更新,因此迭代生成的文档,从先前操作中添加的“临时”字段zoneinfo.timezone
添加一个新的永久字段info.timezone
我做错了什么?是否有其他更可取的方法?每个集合中有数千个文档,因此手工操作是不可取的。您需要记住的一件事是,将zoneInfo
作为数组返回,因此为了使用该字段,您需要在其上运行。然后,您可以使用和简单地重塑文档。尝试:
在最后一步中,如果要更新现有集合,可以添加。由于OP包含一个匹配管道(尽管是空管道),因此可能需要警告使用$out将现有集合的内容替换为聚合结果。因此,如果曾经修改匹配管道以对子集执行聚合,那么那些未包含在匹配中的文档将从现有集合中删除,而不是简单地保持“未修改”@JerrenSaunders我想他是在试图修改整个收藏,因为这个匹配是空的,但你提到:$out总是替换现有的收藏,这很好,谢谢you@JerrenSaunders抢手货是的,源集合和目标集合中的某些文档中没有电话号码,这意味着上述操作的结果文档是原始集合的子集。我不能简单地使用$out删除目标集合中的现有记录。这就是我开始使用两步update()方法的原因,也是为什么我有一个空白的$match查询:我删除了实际的条件以简化我的问题。我的$match是:{'info.phone':{$exists:1}},只复制提供电话号码的联系人的时区信息。@JohnMarquez您是否考虑过使用preserveNullAndEmptyArrays:true
选项$unwind?这将使这些文档保留一个info.phone