MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

$ lookup na ObjectId w tablicy

Aktualizacja 2017

$lookup może teraz bezpośrednio używać tablicy jako pola lokalnego. $unwind nie jest już potrzebne.

Stara odpowiedź

$lookup Etap potoku agregacji nie będzie działał bezpośrednio z tablicą. Główną intencją tego projektu jest „lewe sprzężenie” jako rodzaj sprzężenia „jeden do wielu” (lub tak naprawdę „wyszukiwanie” ) na możliwych powiązanych danych. Ale wartość ma być pojedyncza, a nie tablicą.

Dlatego musisz "zdenormalizować" zawartość przed wykonaniem $lookup operacji, aby to zadziałało. A to oznacza używanie $unwind :

db.orders.aggregate([
    // Unwind the source
    { "$unwind": "$products" },
    // Do the lookup matching
    { "$lookup": {
       "from": "products",
       "localField": "products",
       "foreignField": "_id",
       "as": "productObjects"
    }},
    // Unwind the result arrays ( likely one or none )
    { "$unwind": "$productObjects" },
    // Group back to arrays
    { "$group": {
        "_id": "$_id",
        "products": { "$push": "$products" },
        "productObjects": { "$push": "$productObjects" }
    }}
])

Po $lookup dopasowuje każdy element tablicy wynik jest samą tablicą, więc $unwind ponownie i $group do $push nowe tablice dla końcowego wyniku.

Zwróć uwagę, że wszelkie nieznalezione dopasowania „lewego sprzężenia”, które nie zostaną znalezione, utworzą pustą tablicę dla „productObjects” w danym produkcie, a tym samym negują dokument dla elementu „product”, gdy drugi $unwind nazywa się.

Chociaż bezpośrednia aplikacja do tablicy byłaby przyjemna, tak właśnie działa obecnie, dopasowując pojedynczą wartość do możliwych wielu.

Jako $lookup jest w zasadzie bardzo nowy, obecnie działa tak, jak byłoby to znane tym, którzy znają mangusty jako „słabą wersję dla mężczyzn” .populate() oferowana tam metoda. Różnica polega na tym, że $lookup oferuje przetwarzanie "po stronie serwera" "dołączenia" w przeciwieństwie do klienta i niektóre z "dojrzałości" w $lookup obecnie brakuje tego, co .populate() ofert (takich jak interpolacja wyszukiwania bezpośrednio w tablicy).

W rzeczywistości jest to przydzielony problem do ulepszenia SERVER-22881, więc przy odrobinie szczęścia trafi on w następną wersję lub wkrótce potem.

Zgodnie z zasadą projektowania twoja obecna struktura nie jest ani dobra, ani zła, ale po prostu podlega kosztom ogólnym podczas tworzenia jakiegokolwiek „połączenia”. W związku z tym obowiązuje podstawowa zasada MongoDB na początku, gdzie jeśli „możesz” żyć z danymi „wstępnie połączonymi” w jednym zbiorze, najlepiej to zrobić.

Jeszcze jedna rzecz, którą można powiedzieć o $lookup ogólną zasadą jest to, że intencją „połączenia” jest działanie w odwrotny sposób, niż pokazano tutaj. Więc zamiast trzymać „pokrewne identyfikatory” innych dokumentów w dokumencie „nadrzędnym”, ogólna zasada, która działa najlepiej, to sytuacja, w której „powiązane dokumenty” zawierają odniesienie do „rodzica”.

Więc $lookup można powiedzieć, że „działa najlepiej” z „projektem relacji”, co jest odwrotnością tego, jak coś takiego jak mangusta .populate() wykonuje sprzężenia po stronie klienta. Zamiast tego identyfikując „jeden” w każdym „wielu”, po prostu ściągasz powiązane elementy bez konieczności $unwind najpierw tablica.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Napisz swojego pierwszego doradcę

  2. Flask — złe żądanie Przeglądarka (lub serwer proxy) wysłała żądanie, którego ten serwer nie mógł zrozumieć

  3. MongoDB $asin

  4. MongoDB odrębne polecenie

  5. czy istnieje sposób na automatyczne wygenerowanie ObjectId, gdy model mangusty jest nowy?