sql >> Databáze >  >> NoSQL >> MongoDB

$lookup na ObjectId v poli

Aktualizace z roku 2017

$lookup nyní může přímo používat pole jako místní pole. $unwind již není potřeba.

Stará odpověď

$lookup fáze agregačního potrubí nebude pracovat přímo s polem. Hlavním záměrem návrhu je „levé spojení“ jako typ spojení „jedna k mnoha“ (nebo skutečně „vyhledání“) na možných souvisejících datech. Hodnota však má být singulární, nikoli pole.

Před provedením $lookup proto musíte obsah nejprve "dennormalizovat". operaci, aby to fungovalo. A to znamená použít $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 odpovídá každému členu pole, výsledkem je pole samotné, takže $unwind znovu a $group na $push nová pole pro konečný výsledek.

Všimněte si, že všechny nalezené shody „levého spojení“, které nebudou nalezeny, vytvoří prázdné pole pro „productObjects“ na daném produktu, a tedy negují dokument pro prvek „product“ při druhém $unwind se nazývá.

I když přímá aplikace na pole by byla hezká, v současnosti to funguje tak, že se singulární hodnota shoduje s možným mnoha.

Jako $lookup je v zásadě velmi nový, v současnosti funguje tak, jak by ho znali ti, kteří znají mangusty jako "verze pro chudé muže" .populate() metoda tam nabízená. Rozdíl je v tom, že $lookup nabízí "serverové" zpracování "připojení" na rozdíl od klienta a určitou "vyspělost" v $lookup aktuálně chybí to, co .populate() nabídky (jako je interpolace vyhledávání přímo na poli).

Toto je ve skutečnosti přidělený problém pro vylepšení SERVER-22881, takže s trochou štěstí by se to objevilo v příštím vydání nebo brzy po něm.

Z principu návrhu není vaše současná struktura ani dobrá, ani špatná, ale pouze podléhá režii při vytváření jakéhokoli „spojení“. Jako takový platí základní princip MongoDB na počátku, kdy pokud „umíte“ žít s daty „předpřipojenými“ v jedné kolekci, pak je nejlepší to udělat.

Další věc, kterou lze říci o $lookup Obecným principem je, že záměrem „připojení“ je fungovat opačně, než je zde uvedeno. Takže spíše než ponechání "souvisejících ID" ostatních dokumentů v "nadřazeném" dokumentu, obecný princip, který funguje nejlépe, je ten, kde "související dokumenty" obsahují odkaz na "nadřazený".

Takže $lookup dá se říci, že „funguje nejlépe“ s „návrhem vztahů“, což je opak toho, jak něco jako mangusta .populate() provádí připojení na straně klienta. Tím, že místo toho určíte „jeden“ v každém „mnoho“, pak jednoduše vtáhnete související položky, aniž byste museli $unwind nejprve pole.



  1. Výjimka ověřující MongoCredential a Uncategorized Mongo Db Exception

  2. Jak zvýšit pole v mongodb?

  3. Push Operations v MongoDB

  4. Redis - Indexy s prošlou platností se nesmažou