如何在MongoDB $ lookup中使用变量

时间:2017-03-29 20:24:56

标签: mongodb aggregation-framework

假设我有3个集合,carsbikesvehicles

cars 集合为:

{
  {
    "_id": "car1",
    "carBrand": "Audi",
    "color": "blue"
  },
  {
    "_id": "car2",
    "carBrand": "BMW",
    "color": "white"
  }
}

bikes 集合为:

{
  {
    "_id": "bike1",
    "bikeBrand": "Audi",
    "color": "red"
  },
  {
    "_id": "bike2",
    "carBrand": "BMW",
    "color": "white"
  }
}

vehicles 集合实际上只引用carsbikes个集合作为

{
  {
    "_id": "vehicle1",
    "vehicleType": "cars",
    "vehicleId": "car1"
  },
  {
    "_id": "vehicle2",
    "vehicleType": "cars",
    "vehicleId": "car2"
  },
  {
    "_id": "vehicle3",
    "vehicleType": "bikes",
    "vehicleId": "bike1"
  },
  {
    "_id": "vehicle4",
    "vehicleType": "bikes",
    "vehicleId": "bike2"
  },

}

我想加入vehicles收藏集carsbikes。我尝试将"$vehicleType"设置为$lookup的{​​{1}}字段的变量。但它没有像我预期的那样工作。它根本不加入表格。没有错误。

from

我期待得到像这样的结果

db.collection.aggregate([{

  $lookup: {
      from: "$vehicleType",
      localField: "vehicleId",
      foreignField: "_id",
      as: "vehicleDetails"
  }

}]);

1 个答案:

答案 0 :(得分:3)

如果汽车和自行车没有通用ID,您可以在单独的数组中顺序查找,然后将它们与$setUnion结合使用:

db.vehicles.aggregate([
  {$lookup: {
      from: "cars",
      localField: "vehicleId",
      foreignField: "_id",
      as: "carDetails"
  }},
  {$lookup: {
      from: "bikes",
      localField: "vehicleId",
      foreignField: "_id",
      as: "bikeDetails"
  }},
  {$project: {
     vehicleType: 1,
     vehicleId: 1,      
     vehicleDetails:{$setUnion: [ "$carDetails", "$bikeDetails" ]}
  }},
  {$project: {
      carDetails:0,
      bikeDetails:0,
  }}
]);

否则,在查找之前,您需要使用$facet按类型过滤车辆:

db.vehicles.aggregate([
   {
     $facet: {
         "cars": [
            {$match: {"vehicleType": "cars"}},
            {$lookup: {
               from: "cars",
               localField: "vehicleId",
               foreignField: "_id",
               as: "vehicleDetails"
             }},
         ],
         "bikes": [
            {$match: {"vehicleType": "bikes"}},
            {$lookup: {
               from: "bikes",
               localField: "vehicleId",
               foreignField: "_id",
               as: "vehicleDetails"
             }}
         ]
     }
   },
   {$project: {all: {$setUnion: ["$cars", "$bikes"]}}},
   {$unwind: "$all"},
   {$replaceRoot: { newRoot: "$all" }}
])