sql >> Database >  >> NoSQL >> MongoDB

Mongodb recursieve query werkt niet zoals verwacht met $graphLookup

U kunt $graphLookup gebruiken en andere handige array-operators,

  • $match filter dat records alleen sponsor . hebben is ""
  • $graphLookup om onderliggende records en dieptenummer in depthField level te krijgen
  • $unwind deconstrueren downline array en sta toe dat lege kinderen niet worden verwijderd
  • $sort op diepteniveauveld level in aflopende volgorde
  • $group door id veld en reconstrueer downline reeks
  • $addFields zoek nu de geneste niveaukinderen en wijs ze toe aan het niveau,
    • $reduce om de lus van downline te herhalen reeks.
    • initialiseer standaardveld level standaardwaarde is -1, presentChild is [], prevChild is [] voor het doel van de voorwaarden
    • $let om velden te initialiseren:
      • prev volgens voorwaarde als beide level gelijk zijn, retourneer dan prevChild retourneer anders presentChild
      • current volgens voorwaarde als beide level gelijk zijn, retourneer dan presentChild anders []
    • in om terug te keren naar level veld en prevChild veld uit geïnitialiseerde velden
      • presentChild $filter downline van prev array en return, voeg huidige objecten samen met downline array met behulp van $mergeObjects en concat met current array van let met behulp van $concatArrays
  • $addFields om alleen presentChild te retourneren array omdat we alleen die verwerkte array nodig hadden
db.collection.aggregate([
  { $match: { sponsor: "" } },
  {
    $graphLookup: {
      from: "collection",
      startWith: "$_id",
      connectFromField: "_id",
      connectToField: "sponsor",
      depthField: "level",
      as: "downline"
    }
  },
  {
    $unwind: {
      path: "$downline",
      preserveNullAndEmptyArrays: true
    }
  },
  { $sort: { "downline.level": -1 } },
  {
    $group: {
      _id: "$_id",
      sponsor: { $first: "$sponsor" },
      companyname: { $first: "$companyname" },
      downline: { $push: "$downline" }
    }
  },
  {
    $addFields: {
      downline: {
        $reduce: {
          input: "$downline",
          initialValue: { level: -1, presentChild: [], prevChild: [] },
          in: {
            $let: {
              vars: {
                prev: {
                  $cond: [{ $eq: ["$$value.level", "$$this.level"] }, "$$value.prevChild", "$$value.presentChild"]
                },
                current: {
                  $cond: [{ $eq: ["$$value.level", "$$this.level"] }, "$$value.presentChild", []]
                }
              },
              in: {
                level: "$$this.level",
                prevChild: "$$prev",
                presentChild: {
                  $concatArrays: [
                    "$$current",
                    [
                      {
                        $mergeObjects: [
                          "$$this",
                          {
                            downline: {
                              $filter: {
                                input: "$$prev",
                                as: "e",
                                cond: { $eq: ["$$e.sponsor", "$$this._id"] }
                              }
                            }
                          }
                        ]
                      }
                    ]
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  { $addFields: { downline: "$downline.presentChild" } }
])

Speeltuin




  1. Is MongoDB op de een of andere manier beperkt tot een enkele kern?

  2. hoe een query te tonen tijdens het gebruik van queryannotaties met MongoRepository met lentegegevens

  3. MongoDB wordt afgebroken bij het uitvoeren van het mongod-commando op terminal

  4. Hoe findAndModify te gebruiken in php en mongodb