如何在mongodb中联接多个表

时间:2019-01-02 22:32:47

标签: mongodb mongodb-query aggregation-framework

由于它们的耦合,我目前有5个表需要连接。 使用$ lookup,我可以将Order表与Plan表结合起来并获得所需的内容,但是如何处理其他表呢?

这是每个表,以及它需要连接的ID /表

Plan       - _id, unassignedOrderIds(array)
DriverPlan - _id, planId, orderIds(array), driverId, vehicleId
Driver     - _id, vehicleId
Vehicle    - _id
Orders     - _id

最后,我正在寻找mongoDb以返回已加载UnassignedOrders和DriverPlans的Plan对象。其次是加载了Orders,Driver和Vehicle的DriverPlans。

这是我到目前为止所拥有的:

db.Plan.aggregate([
    // Unwind the source
    { "$unwind": "$UnassignedOrderIds" },
    // Do the lookup matching
    { "$lookup": {
       "from": "Order",
       "localField": "UnassignedOrderIds",
       "foreignField": "_id",
       "as": "UnassignedOrders"
    }},
    // Unwind the result arrays ( likely one or none )
    { "$unwind": "$UnassignedOrders" },
    // Group back to arrays
    { "$group": {
        "_id": "$_id",
        "Order": { "$push": "$Order" },
        "UnassignedOrders": { "$push": "$UnassignedOrders" }
    }}
])

样本文档:

//Plan
{
    "_id" : ObjectId("5c1d244de707b20cece645f1"),
    "UnassignedOrderIds" : [ 
        ObjectId("5c1d247fe707b20cece6462e"), 
        ObjectId("5c1d035de707b20cece63104")
    ]
}

//DriverPlan
[{
    "_id" : ObjectId("123d247fe707b20cece6462e"),
    "PlanId" : ObjectId("5c1d244de707b20cece645f1"),
    "DriverId" : ObjectId("1c1d247fe707b20cece64622"),
    "VehicleId" : ObjectId("3c1d247fe707b20cece64633"),
    "OrderIds": [ 
        ObjectId("5c1d247fe707b20cece64621"), 
        ObjectId("5c1d247fe707b20cece64624")
    ]
},{
    "_id" : ObjectId("123d247fe707b20cece64655"),
    "PlanId" : ObjectId("5c1d244de707b20cece645f1"),
    "DriverId" : ObjectId("2c1d035de707b20cece63104"),
    "VehicleId" : null,
    "OrderIds": [ 
        ObjectId("5c1d247fe707b20cece64625")
    ]
}]

//Orders
[{
    "_id" : ObjectId("5c1d247fe707b20cece6462e"),
    "name" "Order1"
},{
    "_id" : ObjectId("5c1d035de707b20cece63104"),
    "name" "Order2"
},{
    "_id" : ObjectId("5c1d247fe707b20cece64621"),
    "name" "Order3"
},{
    "_id" : ObjectId("5c1d247fe707b20cece64624"),
    "name" "Order4"
},{
    "_id" : ObjectId("5c1d247fe707b20cece64625"),
    "name" "Order5"
}]

//Driver
[{
    "_id" : ObjectId("1c1d247fe707b20cece64622"),
    "vehicleId" : ObjectId("3c1d247fe707b20cece6462e"),
    "name" "Driver1"
},{
    "_id" : ObjectId("2c1d035de707b20cece63104"),
    "vehicleId" : null,
    "name" "Driver2"
},{
    "_id" : ObjectId("3c1d247fe707b20cece64621"),
    "vehicleId" : ObjectId("3c1d035de707b20cece63104"),
    "name" "Driver3"
}]

//Vehicle
[{
    "_id" : ObjectId("3c1d247fe707b20cece6462e"),
    "name" "Vehicle1"
},{
    "_id" : ObjectId("3c1d035de707b20cece63104"),
    "name" "Vehicle2"
},{
    "_id" : ObjectId("3c1d247fe707b20cece64633"),
    "name" "Vehicle3"
}]

预期输出为json对象,如下所示

//Plan with children loaded
{
"_id" : ObjectId("5c1d244de707b20cece645f1"),
"UnassignedOrderIds" : [ 
    ObjectId("5c1d247fe707b20cece6462e"), 
    ObjectId("5c1d035de707b20cece63104")
],
"UnassignedOrders": [{
    "_id" : ObjectId("5c1d247fe707b20cece6462e"),
    "name" "Order1"
},{
    "_id" : ObjectId("5c1d035de707b20cece63104"),
    "name" "Order2"
}],
"DriverPlans" : 
[{
    "_id" : ObjectId("123d247fe707b20cece6462e"),
    "PlanId" : ObjectId("5c1d244de707b20cece645f1"),
    "DriverId" : ObjectId("1c1d247fe707b20cece64622"),
    "Driver": {
        "_id" : ObjectId("1c1d247fe707b20cece64622"),
        "vehicleId" : ObjectId("3c1d247fe707b20cece6462e"),
        "name" "Driver1"
    },
    "VehicleId" : ObjectId("3c1d247fe707b20cece64633"),
    "Vehicle" : {
        "_id" : ObjectId("3c1d247fe707b20cece64633"),
        "name" "Vehicle3"
    },
    "OrderIds": [ 
        ObjectId("5c1d247fe707b20cece64621"), 
        ObjectId("5c1d247fe707b20cece64624")
    ],
    "Orders" : [ 
        {
            "_id" : ObjectId("5c1d247fe707b20cece64621"),
            "name" "Order3"
        },{
            "_id" : ObjectId("5c1d247fe707b20cece64624"),
            "name" "Order4"
        }]
},{
    "_id" : ObjectId("123d247fe707b20cece64655"),
    "PlanId" : ObjectId("5c1d244de707b20cece645f1"),
    "DriverId" : ObjectId("2c1d035de707b20cece63104"),
    "Driver" : {
        "_id" : ObjectId("2c1d035de707b20cece63104"),
        "vehicleId" : null,
        "name" "Driver2"
    }
    "VehicleId" : null,
    "Vehicle" : null,
    "OrderIds": [ 
        ObjectId("5c1d247fe707b20cece64625")
    ],
    "Orders": [{
            "_id" : ObjectId("5c1d247fe707b20cece64625"),
            "name" "Order5"
        }
    ]
}]

}

1 个答案:

答案 0 :(得分:1)

您可以使用以下汇总

db.Plan.aggregate([
  { "$lookup": {
    "from": Order.collection.name,
    "let": { "unassignedOrderIds": "$UnassignedOrderIds" },
    "pipeline": [
      { "$match": { "$expr": { "$in": ["$_id", "$$unassignedOrderIds"] } } }
    ],
    "as": "UnassignedOrderIds"
  }},
  { "$lookup": {
    "from": DriverPlan.collection.name,
    "let": { "planId": "$_id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$PlanId", "$$planId"] } } },
      { "$lookup": {
        "from": Driver.collection.name,
        "let": { "driveId": "$DriverId" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": ["$_id", "$$driveId"] } } }
        ],
        "as": "Driver"
      }},
      { "$lookup": {
        "from": Vehicle.collection.name,
        "let": { "vehicleId": "$VehicleId" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": ["$_id", "$$vehicleId"] } } }
        ],
        "as": "Vehicle"
      }},
      { "$lookup": {
        "from": Order.collection.name,
        "let": { "orderIds": "$OrderIds" },
        "pipeline": [
          { "$match": { "$expr": { "$in": ["$_id", "$$orderIds"] } } }
        ],
        "as": "Orders"
      }}
    ],
    "as": "DriverPlans"
  }}
])

使用mongodb 3.4及以下$lookup语法

db.Plan.aggregate([
  { "$lookup": {
    "from": Order.collection.name,
    "localField": "UnassignedOrderIds",
    "foreignField": "_id",
    "as": "UnassignedOrderIds"
  }},
  { "$lookup": {
    "from": DriverPlan.collection.name,
    "localField": "_id",
    "foreignField": "PlanId",
    "as": "DriverPlans"
  }},
  { "$unwind": "$DriverPlans" },
  { "$lookup": {
    "from": Driver.collection.name,
    "localField": "DriverPlans.DriverId",
    "foreignField": "_id",
    "as": "DriverPlans.Driver"
  }},
  { "$unwind": "$DriverPlans.Driver" },
  { "$lookup": {
    "from": Vehicle.collection.name,
    "localField": "DriverPlans.VehicleId",
    "foreignField": "_id",
    "as": "DriverPlans.Vehicle"
  }},
  { "$unwind": "$DriverPlans.Vehicle" },
  { "$lookup": {
    "from": Order.collection.name,
    "localField": "DriverPlans.OrderIds",
    "foreignField": "_id",
    "as": "DriverPlans.Orders"
  }},
  { "$group": {
    "_id": "$_id",
    "DriverPlans": { "$push": "$DriverPlans" }
  }}
])