2017-03-29 3 views
1

Nehmen wir an, ich habe 3 Sammlungen, cars, bikes, vehicles.

carsSammlung als:

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

bikesSammlung als:

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

und dervehiclesSammlung hat eigentlich nur Verweise auf cars und bikes collectio ns als

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

} 

Ich möchte die vehicles Sammlung mit cars und bikes Sammlungen verbinden. Ich habe versucht, "$vehicleType" als eine Variable zu $lookupfrom Feld zu setzen. Es funktioniert jedoch nicht wie erwartet. Es verbindet sich einfach nicht mit den Tabellen. Keine Fehler.

db.collection.aggregate([{ 

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

}]); 

Ich erwarte ein Ergebnis etwas haben, wie dies

{ 
    { 
    "_id": "vehicle1", 
    "vehicleType": "cars", 
    "vehicleId": "car1", 
    "vehicleDetails": {  
     "_id": "car1", 
     "carBrand": "Audi", 
     "color": "" 
    } 
    }, 
    { 
    "_id": "vehicle2", 
    "vehicleType": "cars", 
    "vehicleId": "car2", 
    "vehicleDetails": { 
     "_id": "car2", 
     "carBrand": "BMW", 
     "color": "white" 

    }, 
    { 
    "_id": "vehicle3", 
    "vehicleType": "bikes", 
    "vehicleId": "bike1", 
    "vehicleDetails": { 
     "_id": "bike1", 
     "bikeBrand": "Audi", 
     "color": "red" 
    } 
    }, 
    { 
    "_id": "vehicle4", 
    "vehicleType": "bikes", 
    "vehicleId": "bike2", 
    "vehicleDetails": { 
     "_id": "bike2", 
     "carBrand": "BMW", 
     "color": "white" 
    } 
    }, 

}  

Antwort

2

Wenn Autos und Motorräder keine gemeinsamen IDs haben, können Sie Nachschlag in separaten Arrays sequentiell, so dass sie dann kombiniert mit $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, 
    }} 
]); 

Andernfalls müssen Sie $facet verwenden Fahrzeuge vor Lookup nach Typ filtern:

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

Vielen Dank. Wie wäre es mit Leistung? Ich nehme an, dass dies "Autos" und "Bikes" Sammlungen unabhängig vom "Fahrzeugtyp" beitreten würde. Wäre es möglich, nach "vehicleType" vor "$ lookup" zu filtern? – pars

+0

ja, wie ich gesagt habe, im allgemeineren Fall müssen Sie Facetten verwenden. Ich habe die Antwort mit Code-Snippet aktualisiert. –

+0

Wunderbar. Danke vielmals. Ich verstehe jetzt mehr. – pars

Verwandte Themen