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

Jak psát unijní dotazy v mongoDB

Provádění sjednocení v MongoDB způsobem „SQL UNION“ je možné pomocí agregací spolu s vyhledáváním v jediném dotazu.

Něco jako toto:

    db.getCollection("AnyCollectionThatContainsAtLeastOneDocument").aggregate(
    [
      { $limit: 1 }, // Reduce the result set to a single document.
      { $project: { _id: 1 } }, // Strip all fields except the Id.
      { $project: { _id: 0 } }, // Strip the id. The document is now empty.

      // Lookup all collections to union together.
      { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
      { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
      { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } },

      // Merge the collections together.
      {
        $project:
        {
          Union: { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
        }
      },

      { $unwind: "$Union" }, // Unwind the union collection into a result set.
      { $replaceRoot: { newRoot: "$Union" } } // Replace the root to cleanup the resulting documents.
    ]);

Zde je vysvětlení, jak to funguje:

  1. Vytvořte instanci aggregate z jakýchkoli kolekce vaší databáze, která obsahuje alespoň jeden dokument. Pokud nemůžete zaručit, že žádná kolekce vaší databáze nebude prázdná, můžete tento problém vyřešit vytvořením nějaké „fiktivní“ kolekce ve vaší databázi obsahující jeden prázdný dokument, který tam bude speciálně pro provádění unijních dotazů.

  2. Udělejte první fázi vašeho kanálu tak, aby byla { $limit: 1 } . Tím se odstraní všechny dokumenty sbírky kromě prvního.

  3. Odstraňte všechna pole zbývajícího dokumentu pomocí $project fáze:

    { $project: { _id: 1 } },
    { $project: { _id: 0 } }
    
  4. Váš agregát nyní obsahuje jeden prázdný dokument. Je čas přidat vyhledávání pro každou kolekci, kterou chcete sjednotit. Můžete použít pipeline pole, chcete-li provést nějaké specifické filtrování, nebo ponechat localField a foreignField jako null, aby odpovídala celé kolekci.

    { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
    { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
    { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
    
  5. Nyní máte agregaci obsahující jeden dokument, který obsahuje 3 pole, jako je toto:

    {
        Collection1: [...],
        Collection2: [...],
        Collection3: [...]
    }
    

    Poté je můžete sloučit do jednoho pole pomocí $project fázi spolu s $concatArrays operátor agregace:

    {
      "$project" :
      {
        "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
      }
    }
    
  6. Nyní máte agregaci obsahující jeden dokument, ve kterém je umístěno pole obsahující vaše sjednocení kolekcí. Co zbývá udělat, je přidat $unwind a $replaceRoot fázi k rozdělení pole do samostatných dokumentů:

    { $unwind: "$Union" },
    { $replaceRoot: { newRoot: "$Union" } }
    
  7. Voilà. Víte, že máte sadu výsledků obsahující kolekce, které jste chtěli sjednotit. Poté můžete přidat další fáze a dále filtrovat, třídit, aplikovat skip() a limit(). V podstatě všechno, co chcete.



  1. Apache HBase I/O – HFfile

  2. Jak pozastavit nebo obnovit úkol s celerem?

  3. Nelze se připojit k mongodb pomocí IP počítače

  4. MongoDB $ sinh