Potrzebuję pobrać całą hierarchię pojedynczego obiektu z bazy danych jako JSON. W rzeczywistości propozycja dotycząca jakiegokolwiek innego rozwiązania pozwalającego osiągnąć ten wynik byłaby wysoce aprobowana. Postanowiłem użyć MongoDB z obsługą $ lookup.Wyszukiwanie zagnieżdżone MongoDB z 3 poziomami
Więc mam trzy kolekcje:
firm
{ "_id" : "2", "name" : "party2" }
{ "_id" : "5", "name" : "party5" }
{ "_id" : "4", "name" : "party4" }
{ "_id" : "1", "name" : "party1" }
{ "_id" : "3", "name" : "party3" }
adres
{ "_id" : "a3", "street" : "Address3", "party_id" : "2" }
{ "_id" : "a6", "street" : "Address6", "party_id" : "5" }
{ "_id" : "a1", "street" : "Address1", "party_id" : "1" }
{ "_id" : "a5", "street" : "Address5", "party_id" : "5" }
{ "_id" : "a2", "street" : "Address2", "party_id" : "1" }
{ "_id" : "a4", "street" : "Address4", "party_id" : "3" }
addressComment
{ "_id" : "ac2", "address_id" : "a1", "comment" : "Comment2" }
{ "_id" : "ac1", "address_id" : "a1", "comment" : "Comment1" }
{ "_id" : "ac5", "address_id" : "a5", "comment" : "Comment6" }
{ "_id" : "ac4", "address_id" : "a3", "comment" : "Comment4" }
{ "_id" : "ac3", "address_id" : "a2", "comment" : "Comment3" }
Muszę pobrać wszystkie strony z odpowiednimi adresami i komentarzami adresowymi jako częścią rekordu. Moja agregacja:
db.party.aggregate([{
$lookup: {
from: "address",
localField: "_id",
foreignField: "party_id",
as: "address"
}
},
{
$unwind: "$address"
},
{
$lookup: {
from: "addressComment",
localField: "address._id",
foreignField: "address_id",
as: "address.addressComment"
}
}])
Rezultat jest dość dziwny. Niektóre zapisy są w porządku. Brakuje Party z _id 4 (nie ma adresu). Ponadto w zestawie wyników są dwie osoby: 1, ale z innymi adresami:
{
"_id": "1",
"name": "party1",
"address": {
"_id": "2",
"street": "Address2",
"party_id": "1",
"addressComment": [{
"_id": "3",
"address_id": "2",
"comment": "Comment3"
}]
}
}{
"_id": "1",
"name": "party1",
"address": {
"_id": "1",
"street": "Address1",
"party_id": "1",
"addressComment": [{
"_id": "1",
"address_id": "1",
"comment": "Comment1"
},
{
"_id": "2",
"address_id": "1",
"comment": "Comment2"
}]
}
}{
"_id": "3",
"name": "party3",
"address": {
"_id": "4",
"street": "Address4",
"party_id": "3",
"addressComment": []
}
}{
"_id": "5",
"name": "party5",
"address": {
"_id": "5",
"street": "Address5",
"party_id": "5",
"addressComment": [{
"_id": "5",
"address_id": "5",
"comment": "Comment5"
}]
}
}{
"_id": "2",
"name": "party2",
"address": {
"_id": "3",
"street": "Address3",
"party_id": "2",
"addressComment": [{
"_id": "4",
"address_id": "3",
"comment": "Comment4"
}]
}
}
Proszę, pomóżcie mi z tym. Jestem nowicjuszem w MongoDB, ale czuję, że może zrobić to, czego potrzebuję.
Tank ty Shad! Jest jeden mały problem z zapisem 4 jednak: '{ \t "_id": "4", \t "name": "Imprezka! 4" \t "adres": [{ \t \t "addressComment": [] \t}] } ' }' } Jak widać - adres powinien być pusty, ale zamiast tego jest pusty ... Czy możemy pominąć adres, jeśli jego adres jest pusty? W innym przypadku ten adres będzie uznawany za rekord. – Yuriy
W rzeczywistości widzę, że dostarczone rozwiązanie działa zgodnie z oczekiwaniami, zgodnie z opisem nowego pola "preserveNullAndEmptyArrays" dla operacji $ unwind (od wersji 3.2). Teraz możemy pominąć krok "$ project" i określić ten "$ unwind" zamiast prostego: '$ unwind: {path:" $ address ", zachowajNullAndEmptyArrays: true}'.Przyjmuję twoją odpowiedź, dziękuję za szybką i jasną odpowiedź! – Yuriy
@Shad Mam dość podobne pytanie. Tutaj kod OP ma tylko jedną właściwość o nazwie 'name' w kolekcji' party' i stąd użyłeś '$ first', aby pobrać ją w' $ group'. Przypuśćmy, że mam 10 lub więcej właściwości, czy jest jakiś sposób, aby automatycznie uzyskać wszystkie właściwości, nie wspominając o każdej z nich indywidualnie? – Xyroid