sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan skriver du fagforeningsforespørgsler i mongoDB

At lave fagforeninger i MongoDB på en "SQL UNION"-måde er muligt ved at bruge aggregeringer sammen med opslag i en enkelt forespørgsel.

Noget som dette:

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

Her er forklaringen på, hvordan det virker:

  1. Instantiér et aggregate ud af enhver samling af din database, der har mindst ét ​​dokument i sig. Hvis du ikke kan garantere, at en samling af din database ikke vil være tom, kan du omgå dette problem ved at oprette en slags 'dummy'-samling i din database, der indeholder et enkelt tomt dokument, der vil være der specifikt til at lave fagforeningsforespørgsler.

  2. Gør den første fase af din pipeline til at være { $limit: 1 } . Dette fjerner alle dokumenter fra samlingen undtagen det første.

  3. Fjern alle felterne i det resterende dokument ved at bruge $project stadier:

    { $project: { _id: 1 } },
    { $project: { _id: 0 } }
     
  4. Dit aggregat indeholder nu et enkelt, tomt dokument. Det er tid til at tilføje opslag for hver samling, du vil forene sammen. Du kan bruge pipeline felt for at udføre en specifik filtrering, eller forlad localField og foreignField som null for at matche hele samlingen.

    { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
    { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
    { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
     
  5. Du har nu et aggregat, der indeholder et enkelt dokument, der indeholder 3 arrays som dette:

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

    Du kan derefter flette dem sammen til et enkelt array ved hjælp af et $project fase sammen med $concatArrays aggregeringsoperatør:

    {
      "$project" :
      {
        "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
      }
    }
     
  6. Du har nu et aggregat, der indeholder et enkelt dokument, hvori der er placeret et array, der indeholder din forening af samlinger. Det, der mangler at blive gjort, er at tilføje en $unwind og en $replaceRoot trin for at opdele dit array i separate dokumenter:

    { $unwind: "$Union" },
    { $replaceRoot: { newRoot: "$Union" } }
     
  7. Voilà. Du ved, at du har et resultatsæt, der indeholder de samlinger, du ønskede at forene sammen. Du kan derefter tilføje flere stadier for at filtrere det yderligere, sortere det, anvende skip() og limit(). Stort set alt, hvad du ønsker.



  1. Heroku Redis - GUI og hukommelsesoptimering

  2. Tilslutning af Heroku App til Atlas MongoDB Cloud-tjeneste

  3. MongoDB $literal

  4. MongoDB $substrBytes