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

Mongodb rekursiv forespørgsel fungerer ikke som forventet med $graphLookup

Du kan bruge $graphLookup og andre nyttige array-operatorer,

  • $match filter, at poster kun har sponsor er ""
  • $graphLookup for at få underordnede poster og dybdenummer i depthField level
  • $unwind dekonstruere downline array og tillad ikke at fjerne tomme børn
  • $sort efter dybdeniveaufelt level i faldende rækkefølge
  • $group efter id felt og rekonstruer downline matrix
  • $addFields find nu de indlejrede niveauunderordnede niveauer og alloker til dets niveau,
    • $reduce at gentage løkken af ​​downline array.
    • initialiser standardfelt level standardværdien er -1, presentChild er [], prevChild er [] til formålet med betingelserne
    • $let for at initialisere felter:
      • prev som pr betingelse, hvis begge level er lige så returner prevChild ellers returner presentChild
      • current som pr betingelse, hvis begge level er lige så returner presentChild ellers []
    • in for at returnere level felt og prevChild felt fra initialiserede felter
      • presentChild $filter downline fra prev array og returner, flet aktuelle objekter med downline array ved hjælp af $mergeObjects og sammenkæde med current array af lad ved hjælp af $concatArrays
  • $addFields for kun at returnere presentChild array, fordi vi kun krævede det behandlede array
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" } }
])

Legeplads




  1. MongoDB, udførelse af forespørgsel ved regulært udtryk på indekserede felter

  2. Hvordan sender jeg et objekt fra MongoDB til jade?

  3. Ingen server valgt af WritableServerSelector fra klyngen

  4. MongoDB $opslag på indlejret dokument