sql >> Database >  >> NoSQL >> MongoDB

Voorwaarden voor meerdere deelname met behulp van de $lookup-operator

We kunnen meerdere deelnamevoorwaarden doen met de $lookup aggregatiepijplijnoperator in versie 3.6 en nieuwer.

We moeten de waarden van de velden toewijzen aan een variabele met behulp van de let optioneel veld; je krijgt dan toegang tot die variabelen in de pipeline veldstadia waar u de pijplijn specificeert die op de collecties moet worden uitgevoerd.

Merk op dat in de $match stadium gebruiken we de $expr evaluatiequery-operator om de waarde van de velden te vergelijken.

De laatste fase in de pijplijn is de $replaceRoot aggregatiepijplijnfase waarin we eenvoudig de $lookup . samenvoegen resultaat met een deel van de $$ROOT document met behulp van de $mergeObjects telefoniste.

db.collection2.aggregate([
       {
          $lookup: {
             from: "collection1",
             let: {
                firstUser: "$user1",
                secondUser: "$user2"
             },
             pipeline: [
                {
                   $match: {
                      $expr: {
                         $and: [
                            {
                               $eq: [
                                  "$user1",
                                  "$$firstUser"
                               ]
                            },
                            {
                               $eq: [
                                  "$user2",
                                  "$$secondUser"
                               ]
                            }
                         ]
                      }
                   }
                }
             ],
             as: "result"
          }
       },
       {
          $replaceRoot: {
             newRoot: {
                $mergeObjects:[
                   {
                      $arrayElemAt: [
                         "$result",
                         0
                      ]
                   },
                   {
                      percent1: "$$ROOT.percent1"
                   }
                ]
             }
          }
       }
    ]
)

Deze pijplijn levert iets op dat er als volgt uitziet:

{
    "_id" : ObjectId("59e1ad7d36f42d8960c06022"),
    "user1" : 1,
    "user2" : 2,
    "percent" : 0.3,
    "percent1" : 0.56
}

Als u niet op versie 3.6+ zit, kunt u eerst deelnemen door een van uw velden te gebruiken, zeg "gebruiker1" en vanaf daar kunt u de array van het overeenkomende document afwikkelen met behulp van de $unwind aggregatie pijpleiding operator. De volgende fase in de pijplijn is de $redact fase waarin u die documenten uitfiltert waar de waarde van "user2" uit de "joined" collectie en het invoerdocument niet gelijk zijn met behulp van de $$KEEP en $$PRUNE systeem variabelen. U kunt uw document vervolgens een nieuwe vorm geven in $project podium.

db.collection1.aggregate([
    { "$lookup": { 
        "from": "collection2", 
        "localField": "user1", 
        "foreignField": "user1", 
        "as": "collection2_doc"
    }}, 
    { "$unwind": "$collection2_doc" },
    { "$redact": { 
        "$cond": [
            { "$eq": [ "$user2", "$collection2_doc.user2" ] }, 
            "$$KEEP", 
            "$$PRUNE"
        ]
    }}, 
    { "$project": { 
        "user1": 1, 
        "user2": 1, 
        "percent1": "$percent", 
        "percent2": "$collection2_doc.percent"
    }}
])

die produceert:

{
    "_id" : ObjectId("572daa87cc52a841bb292beb"),
    "user1" : 1,
    "user2" : 2,
    "percent1" : 0.56,
    "percent2" : 0.3
}

Als de documenten in uw verzamelingen dezelfde structuur hebben en u merkt dat u deze bewerking vaak uitvoert, kunt u overwegen om de twee verzamelingen samen te voegen tot één verzameling of de documenten in die verzamelingen in een nieuwe verzameling in te voegen.

db.collection3.insertMany(
    db.collection1.find({}, {"_id": 0})
    .toArray()
    .concat(db.collection2.find({}, {"_id": 0}).toArray())
)

Dan $group uw documenten door "gebruiker1" en "gebruiker2"

db.collection3.aggregate([
    { "$group": {
        "_id": { "user1": "$user1", "user2": "$user2" }, 
        "percent": { "$push": "$percent" }
    }}
])

wat oplevert:

{ "_id" : { "user1" : 1, "user2" : 2 }, "percent" : [ 0.56, 0.3 ] }


  1. Velden hernoemen in hash voor meerdere sleutels in Redis

  2. Het is niet mogelijk om een ​​mongodb-document te vergrendelen. Wat als ik dat nodig heb?

  3. MongoDB groeperen op waarden in een matrixveld

  4. Hoe krijg je alle tellingen van het mangoestmodel?