【问题标题】:$unwind and $group multiple times$unwind 和 $group 多次
【发布时间】:2019-10-02 08:16:44
【问题描述】:

我有以下样本集合Contract

/* 1 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3"
                }
            ]
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture 3",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 4",
                    "ContactId" : "Contact_3"
                }
            ]
        }
    ]
}

/* 2 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3"
                }
            ]
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3"
                }
            ]
        }
    ]
}

ContactIdVehicleId 需要由 lookup 从各自的集合中检索。为此,我进行了以下查询:

    db.getCollection('Contract').aggregate([
    {$lookup:
        { 
        from: "Contact",
        localField: "ContactId",
        foreignField: "_id",
        as: "Contact"
        }
     },
     {$unwind: "$Contact"},
     {$unwind: "$Specifications"},
     {$lookup:
        { 
        from: "Vehicle",
        localField: "Specifications.VehicleId",
        foreignField: "_id",
        as: "Specifications.Vehicle"
        }
     },
     {$unwind: "$Specifications.Vehicle"},
     {$unwind: "$Specifications.Customizations"},
     {$lookup:
        { 
        from: "Contact",
        localField: "Specifications.Customizations.ContactId",
        foreignField: "_id",
        as: "Specifications.Customizations.Contact"
        }
     },
     {$unwind: "$Specifications.Customizations.Contact"}
])

我得到这样的东西:

/* 1 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : {
        "Description" : "Descrizione1",
        "VehicleId" : "Vehicle_1",
        "Vehicle" : {
            "_id" : "Vehicle_1",
            "FrameNumber" : "asdasd33",
        },
        "Customizations" : {
            "Description" : "Random furniture",
            "ContactId" : "Contact_5",
            "Contact" : {
                "_id" : "Contact_5",
                "Name" : "Nome5"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_1",
        "Name" : "Nome"
    }
}

/* 2 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : {
        "Description" : "Descrizione1",
        "VehicleId" : "Vehicle_1",
        "Vehicle" : {
            "_id" : "Vehicle_1",
            "FrameNumber" : "asdasd33",
        },
        "Customizations" : {
            "Description" : "Random furniture 2",
            "ContactId" : "Contact_3",
            "Contact" : {
                "_id" : "Contact_3",
                "Name" : "Nome3"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_1",
        "Name" : "Nome"
    }
}

/* 3 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : {
        "Description" : "Descrizione2",
        "VehicleId" : "Vehicle_2",
        "Vehicle" : {
            "_id" : "Vehicle_2",
            "FrameNumber" : "frame2",
        },
        "Customizations" : {
            "Description" : "Random furniture 3",
            "ContactId" : "Contact_5",
            "Contact" : {
                "_id" : "Contact_5",
                "Name" : "Nome5"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_1",
        "Name" : "Nome"
    }
}

/* 4 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : {
        "Description" : "Descrizione2",
        "VehicleId" : "Vehicle_2",
        "Vehicle" : {
            "_id" : "Vehicle_2",
            "FrameNumber" : "frame2",
        },
        "Customizations" : {
            "Description" : "Random furniture 4",
            "ContactId" : "Contact_3",
            "Contact" : {
                "_id" : "Contact_3",
                "Name" : "Nome3"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_1",
        "Name" : "Nome"
    }
}

/* 5 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : {
        "Description" : "Descrizione1",
        "VehicleId" : "Vehicle_1",
        "Vehicle" : {
            "_id" : "Vehicle_1",
            "FrameNumber" : "asdasd33",
        },
        "Customizations" : {
            "Description" : "Random furniture",
            "ContactId" : "Contact_5",
            "Contact" : {
                "_id" : "Contact_5",
                "Name" : "Nome5"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_2",
        "Name" : "Nome"
    }
}

/* 6 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : {
        "Description" : "Descrizione1",
        "VehicleId" : "Vehicle_1",
        "Vehicle" : {
            "_id" : "Vehicle_1",
            "FrameNumber" : "asdasd33",
        },
        "Customizations" : {
            "Description" : "Random furniture 2",
            "ContactId" : "Contact_3",
            "Contact" : {
                "_id" : "Contact_3",
                "Name" : "Nome3"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_2",
        "Name" : "Nome"
    }
}

/* 7 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : {
        "Description" : "Descrizione2",
        "VehicleId" : "Vehicle_2",
        "Vehicle" : {
            "_id" : "Vehicle_2",
            "FrameNumber" : "frame2",
        },
        "Customizations" : {
            "Description" : "Random furniture",
            "ContactId" : "Contact_5",
            "Contact" : {
                "_id" : "Contact_5",
                "Name" : "Nome5"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_2",
        "Name" : "Nome"
    }
}

/* 8 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : {
        "Description" : "Descrizione2",
        "VehicleId" : "Vehicle_2",
        "Vehicle" : {
            "_id" : "Vehicle_2",
            "FrameNumber" : "frame2",
        },
        "Customizations" : {
            "Description" : "Random furniture 2",
            "ContactId" : "Contact_3",
            "Contact" : {
                "_id" : "Contact_3",
                "Name" : "Nome3"
            }
        }
    },
    "Contact" : {
        "_id" : "Contact_2",
        "Name" : "Nome"
    }
}

如何将所有内容分组以获取 2 个合同作为起点,但要使用从查找中获得的所有信息?我想按 Contract _id 字段分组,但 2 个嵌套数组并没有真正帮助这样做。

编辑:预期结果:

/* 1 */
{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Contact" : {
        "_id" : "Contact_1",
        "Name" : "Nome"
    },
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Vehicle" : {
                "_id" : "Vehicle_1",
                "FrameNumber" : "asdasd33"
            },
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5",
                    "Contact" : {
                        "_id" : "Contact_5",
                        "Name" : "Nome5"
                    }
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3",
                    "Contact" : {
                        "_id" : "Contact_3",
                        "Name" : "Nome3"
                    }
                }
            ]
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Vehicle" : {
                "_id" : "Vehicle_2",
                "FrameNumber" : "frame2"
            },
            "Customizations" : [ 
                {
                    "Description" : "Random furniture 3",
                    "ContactId" : "Contact_5",
                    "Contact" : {
                        "_id" : "Contact_5",
                        "Name" : "Nome5"
                    }
                }, 
                {
                    "Description" : "Random furniture 4",
                    "ContactId" : "Contact_3",
                    "Contact" : {
                        "_id" : "Contact_3",
                        "Name" : "Nome3"
                    }
                }
            ]
        }
    ]
}

/* 2 */
{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Contact" : {
        "_id" : "Contact_2",
        "Name" : "Nome2"
    }
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Vehicle" : {
                "_id" : "Vehicle_1",
                "FrameNumber" : "asdasd33"
            },
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5",
                    "Contact" : {
                        "_id" : "Contact_5",
                        "Name" : "Nome5"
                    }
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3",
                    "Contact" : {
                        "_id" : "Contact_3",
                        "Name" : "Nome3"
                    }
                }
            ]
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Vehicle" : {
                "_id" : "Vehicle_1",
                "FrameNumber" : "frame2"
            },
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5",
                    "Contact" : {
                        "_id" : "Contact_5",
                        "Name" : "Nome5"
                    }
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3",
                    "Contact" : {
                        "_id" : "Contact_3",
                        "Name" : "Nome3"
                    }
                }
            ]
        }
    ]
}

【问题讨论】:

  • 能否提供联系人收集数据和预期结果
  • @AshwanthMadhav 我修复了查找,并添加了预期的结果。这是起始文档,包含从查找中检索到的所有信息
  • 我需要联系人收集文件。它只是名称和 ID?
  • 是的,还有Vehicle,只是为了更容易。真正的问题可以进一步简化。我需要倒带{$unwind: "$Specifications"}, {$unwind: "$Specifications.Customizations"} 部分。你可以想象一个前一个对象的聚合,只用这两条指令,然后回到前一个对象。查找并不重要

标签: mongodb group-by mongodb-query aggregation-framework


【解决方案1】:

您可以使用以下聚合。

db.getCollection("Contract").aggregate([
  { "$lookup": {
    "from": "Contact",
    "localField": "ContactId",
    "foreignField": "_id",
    "as": "Contact"
  }},
  { "$unwind": "$Contact" },
  { "$unwind": "$Specifications" },
  { "$lookup": {
    "from": "Vehicle",
    "localField": "Specifications.VehicleId",
    "foreignField": "_id",
    "as": "Specifications.Vehicle"
  }},
  { "$unwind": "$Specifications.Vehicle" },
  { "$unwind": "$Specifications.Customizations" },
  { "$lookup": {
    "from": "Contact",
    "localField": "Specifications.Customizations.ContactId",
    "foreignField": "_id",
    "as": "Specifications.Customizations.Contact"
  }},
  { "$unwind": "$Specifications.Customizations.Contact" },
  { "$group": {
    "_id": {
      "_id"; "$_id",
      "Description": "$Specifications.Description"
    },
    "ContactId": { "$first": "$ContactId" },
    "Contact": { "$first": "$Contact" },
    "Specifications": {
      "$push": "$Specifications.Customizations"
    }
  }},
  { "$group": {
    "_id": "$_id._id",
    "ContactId": { "$first": "$ContactId" },
    "Contact": { "$first": "$Contact" },
    "Specifications": {
      "$push": {
        "Description": "$_id.Description"
        "Customizations": "$Specifications"
      }
    }
  }}
])

【讨论】:

  • 你好,这真的很接近我的需要,在Customizations数组中,有一个名为Customizations本身的对象,怎么可能删除它? "Customizations" : [ { "Customizations" : { // remove this one "Description" : "Random furniture 3",
  • 更新了我的答案。那是我的错
  • 嗨,我刚刚发现,当我将 Specifications 作为空数组时,在分组时,我得到一个内部元素为空的数组。我将为这个问题创建一个新问题。标记你有问题吗?
  • 不可以继续
  • 嗨,这是一个新问题,我使用了和这个相同的结构link
【解决方案2】:
db.getCollection('Contract').aggregate([  
{  
  $lookup:{  
     from:"contact",
     localField:"ContactId",
     foreignField:"_id",
     as:"contact"
  }
},
{  
  $unwind:{  
     path:"$contact",
     preserveNullAndEmptyArrays:true
  }
},
{  
  $unwind:{  
     path:"$Specifications",
     preserveNullAndEmptyArrays:true
  }
},
{  
  $unwind:{  
     path:"$Specifications.Customizations",
     preserveNullAndEmptyArrays:true
  }
},
{  
  $lookup:{  
     from:"contact",
     localField:"Specifications.Customizations.ContactId",
     foreignField:"_id",
     as:"details"
  }
},
{  
  $unwind:{  
     path:"$details",
     preserveNullAndEmptyArrays:true
  }
},
{  
  $project:{  
     ContactId:1,
     Specifications:1,
     details:1,
     contact:1
  }
},
{  
  $addFields:{  
     "Specifications.Customizations.Contact":"$details",

  }
},
{  
  $group:{  
     _id:{  
        _id:"$_id",
        ContactId:"$ContactId",
        spec:"$Specifications.Description",
        VehicleId:"$Specifications.VehicleId"
     },
     Customizations:{  
        $addToSet:"$Specifications.Customizations"
     },
     contact:{  
        $first:"$contact"
     }
  },

},
{  
  $project:{  
     spec:{  
        Description:"$_id.spec",
        VehicleId:"$_id.VehicleId",
        Customizations:"$Customizations"
     },
     contact:1
  },

},
{  
  $group:{  
     _id:"$_id._id",
     ContactId:{  
        $first:"$_id.ContactId"
     },
     contact:{  
        $first:"$contact"
     },
     Specifications:{  
        $addToSet:"$spec"
     }
  }
}
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2019-09-03
    • 2017-07-04
    • 2021-06-28
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多