Faktisk er det andet svar forkert. Det er muligt at lave et opslag på et DBref-felt i din aggregator, og du behøver ikke mapreduce til det.
Løsning
db.A.aggregate([{ $project:{ B_fk:{ $map:{ input:{ $map:{ input:"$bid", i:{ $arrayElemAt:[{$objectToArray:"$$this"}, 1] }, } }, i:"$$this.v"}}, }}, { $lookup:{ from:"B", localField:"B_fk", fremmedField:"_id ", as:"B" }}])
resultat
{ "_id" :ObjectId("59bb79df1e9c00162566f581"), "B_fk" :null, "B" :[ ]},{ "_id" :ObjectId("582abcd85d2dfa67f44127"), "B_127" ("582abcd85d2dfa67f44127e0"), ObjectId("582abcd85d2dfa67f44127e1") ], "B" :[ { "_id" :ObjectId("582abcd85d2dfa67f44127e0":") Number "Intstatus" :") Number "Intstatus" :", Number "Intstatus" :") ") } ]}
Kort forklaring
Gå gennem DBRef'erne med $map, opdel hver DBref i et array, behold kun $id-feltet, og slip derefter af k:v-formatet med $$this.v, behold kun ObjectId'et og fjern resten. Du kan nu slå op på ObjectId.
Trin-for-trin forklaring
Inden for aggregatoren kan en DBRef BSON-type håndteres som et objekt med to eller tre felter (ref, id og db).
Hvis du gør:
db.A.aggregate([ { $project:{ First_DBref_as_array:{$objectToArray:{$arrayElemAt:["$bid",0]}}, Second_DBref_as_array:{$objectToArray:{$arrayElemAt:[ "$bid",1]}}, } },])
Dette er resultatet:
{"_id" :ObjectId("582abcd85d2dfa67f44127e1"),"First_DBref_as_array :[ { "k" :"$ref", "v" :"B" }, { "k" :"$id" , "v" :ObjectId("582abcd85d2dfa67f44127e0") }],"Second_DBref_as_array" :[ { "k" :"$ref", "v" :"B" }, { "k" :"$id", "v " :ObjectId("582abcd85d2dfa67f44127e0") }]}
Når du har transformeret en dbref til et array, kan du slippe af med de ubrugelige felter ved kun at forespørge værdien ved indeks 1, sådan her:
db.A.aggregate([ { $project:{ First_DBref_as_array:{$arrayElemAt:[{$objectToArray:{$arrayElemAt:["$bid",0]}},1]}, Second_DBref_as_array:{$arrayElemAt:[{$objectToArray:{$arrayElemAt:["$bid",0]}},1]}, } },])
resultat:
{ "_id" :ObjectId("582abcd85d2dfa67f44127e1"), "First_DBref_as_array" :{ "k" :"$id", "v" :ObjectId("582abcd85d2dfa67f44127e1") { "k" :"$id", "v" :ObjectId("582abcd85d2dfa67f44127e1") k" :"$id", "v" :ObjectId("582abcd85d2dfa67f44127e0") }}
Så kan du endelig komme til den værdi, du ønsker, ved at pege på "$myvalue.v", ligesom denne
db.A.aggregate([ { $project:{ first_DBref_as_array:{$arrayElemAt:[{$objectToArray:{$arrayElemAt:["$bid",0]}},1]}, second_DBref_as_array:{$arrayElemAt:[{$objectToArray:{$arrayElemAt:["$bid",0]}},1]}, } }, { $project:{ first_DBref_as_ObjectId:"$first_DBref_as_array.v", second_DBref_as_ObjectId:"$second" .v" } }])
resultat:
{ "_id" :ObjectId("582abcd85d2dfa67f44127e1"), "first_DBref_as_ObjectId" :ObjectId("582abcd85d2dfa67f44127e0"), "second_DBref_as_ObjectId("582abcd85d2dfa67f44127e0"), "second_DBref_as_ObjectId6" (second_DBref_as_ObjectId6)582abcd85d2dfa67f44127e0"), "second_DBref_as_ObjectId6(44127e0")
I en normal pipeline behøver du naturligvis ikke alle disse overflødige trin, ved at bruge et indlejret $map kan du nå det samme resultat på én gang :
db.A.aggregate([ { $project:{ B_fk:{ $map :{input:{ $map:{ input:"$bid", i:{ $arrayElemAt:[{$objectToArray:"$$this"}, 1 ]}, } }, i:"$$this.v"}}, } }, ])
resultat:
{ "_id" :ObjectId("582abcd85d2dfa67f44127e1"), "B_fk" :[ ObjectId("582abcd85d2dfa67f44127e0"), ObjectId("582abcd85d4dfa")] 127
Jeg håber, at forklaringen er klar nok, hvis ikke, er du velkommen til at spørge.