sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongo hvordan man $lookup med DBRef

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.



  1. Er der nogen måde at gendanne nyligt slettede dokumenter i MongoDB?

  2. Føj data til eksisterende gridfs-fil

  3. Om char b-præfiks i Python3.4.1-klienten opret forbindelse til redis

  4. Indsættelse af en liste i en anden liste i Redis