sql >> Database >  >> NoSQL >> MongoDB

Hoe unie-query's in mongoDB te schrijven?

Unions maken in MongoDB op een 'SQL UNION'-manier is mogelijk met behulp van aggregaties samen met lookups, in een enkele zoekopdracht.

Zoiets als dit:

    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.
    ]);

Hier is de uitleg van hoe het werkt:

  1. Instantieer een aggregate uit elke verzameling van uw database die ten minste één document bevat. Als u niet kunt garanderen dat een verzameling van uw database niet leeg is, kunt u dit probleem omzeilen door in uw database een soort 'dummy'-verzameling te maken met daarin een enkel leeg document dat speciaal is bedoeld voor het uitvoeren van union-query's.

  2. Maak de eerste fase van uw pijplijn { $limit: 1 } . Hiermee worden alle documenten van de collectie verwijderd, behalve de eerste.

  3. Verwijder alle velden van het resterende document met behulp van $project stadia:

    { $project: { _id: 1 } },
    { $project: { _id: 0 } }
    
  4. Uw aggregaat bevat nu één leeg document. Het is tijd om zoekopdrachten toe te voegen voor elke verzameling die u wilt samenvoegen. U mag de pipeline . gebruiken veld om specifiek te filteren, of verlaat localField en foreignField als null om bij de hele collectie te passen.

    { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
    { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
    { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
    
  5. U hebt nu een aggregaat dat een enkel document bevat dat 3 arrays bevat zoals deze:

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

    Je kunt ze dan samenvoegen tot een enkele array met behulp van een $project stage samen met de $concatArrays aggregatie-operator:

    {
      "$project" :
      {
        "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
      }
    }
    
  6. U hebt nu een aggregaat dat één enkel document bevat, waarin zich een array bevindt die uw unie van verzamelingen bevat. Wat nog moet gebeuren, is het toevoegen van een $unwind en een $replaceRoot stage om uw array op te splitsen in afzonderlijke documenten:

    { $unwind: "$Union" },
    { $replaceRoot: { newRoot: "$Union" } }
    
  7. Voila. U weet dat u een resultatenset hebt met de collecties die u samen wilde voegen. U kunt dan meer fasen toevoegen om het verder te filteren, sorteren, skip() en limit() toepassen. Vrijwel alles wat je wilt.



  1. Hoe MongoDB machine learning mogelijk maakt

  2. PyMongo -- cursor iteratie

  3. Hoe kan ik verbinding maken met MongoDB Atlas met Robomongo?

  4. Hoe waarden bijwerken met pymongo?