sql >> Databasteknik >  >> NoSQL >> MongoDB

Mongodb rekursiva fråga fungerar inte som förväntat med $graphLookup

Du kan använda $graphLookup och andra användbara arrayoperatorer,

  • $match filter som bara har sponsor är ""
  • $graphLookup för att få underordnade poster och djupnummer i depthField level
  • $unwind dekonstruera downline array och tillåt för att inte ta bort tomma barn
  • $sort efter djupnivåfält level i fallande ordning
  • $group av id och rekonstruera downline array
  • $addFields hitta nu de kapslade nivåernas barn och allokera till dess nivå,
    • $reduce för att upprepa loop av downline array.
    • initiera standardfältet level standardvärdet är -1, presentChild är [], prevChild är [] för villkoren
    • $let för att initiera fält:
      • prev enligt villkor om båda level är lika och returnera sedan prevChild returnera annars presentChild
      • current enligt villkor om båda level är lika och returnera sedan presentChild annars []
    • in för att returnera level field och prevChild fält från initierade fält
      • presentChild $filter downline från prev array och return, slå samman aktuella objekt med downline array med $mergeObjects och sammanfoga med current array of let med $concatArrays
  • $addFields för att endast returnera presentChild array eftersom vi bara krävde den bearbetade arrayen
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" } }
])

Lekplats




  1. Installera Apache CouchDB på CentOS 7

  2. Mongoose findById() i ett objekt av kapslade scheman / underdokument - aggregering

  3. Hur ställer jag in en timeout för en Mongoose-fråga?

  4. Kan inte ansluta till en Mongodb-pod i Kubernetes (Anslutning nekad)