$ unwind和$ group多次

时间:2019-05-15 08:44:30

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

我有以下示例集合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为起点,但要包含从查找中获得的所有信息?我想按Contract _id字段分组,但是2个嵌套数组实际上并没有帮助。

编辑:ExpectedResult:

/* 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"
                    }
                }
            ]
        }
    ]
}

2 个答案:

答案 0 :(得分:2)

您可以使用以下汇总。

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"
      }
    }
  }}
])

答案 1 :(得分:0)

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"
     }
  }
}
])