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

Lav nodetræ med rekursiv tabel med Express og Mongo

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

  • $match filter, at poster kun har parent_id er null
  • $graphLookup for at få underordnede poster og dybdenummer i depthField level
  • $unwind dekonstruere children array og tillad ikke at fjerne tomme børn
  • $sort efter dybdeniveaufelt level i faldende rækkefølge
  • $group efter id felt og rekonstruer children matrix
db.collection.aggregate([
  { $match: { parent_id: null } },
  {
    $graphLookup: {
      from: "collection",
      startWith: "$id",
      connectFromField: "id",
      connectToField: "parent_id",
      depthField: "level",
      as: "children"
    }
  },
  {
    $unwind: {
      path: "$children",
      preserveNullAndEmptyArrays: true
    }
  },
  { $sort: { "children.level": -1 } },
  {
    $group: {
      _id: "$id",
      parent_id: { $first: "$parent_id" },
      name: { $first: "$name" },
      type: { $first: "$type" },
      category: { $first: 1 },
      children: { $push: "$children" }
    }
  },
  • $addFields find nu de indlejrede niveauunderordnede niveauer og alloker til dets niveau,
    • $reducere til iteration af children 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 children fra prev array og returner, flet nuværende objekter med children 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
  {
    $addFields: {
      children: {
        $reduce: {
          input: "$children",
          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",
                          {
                            children: {
                              $filter: {
                                input: "$$prev",
                                as: "e",
                                cond: { $eq: ["$$e.parent_id", "$$this.id"] }
                              }
                            }
                          }
                        ]
                      }
                    ]
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $addFields: {
      id: "$_id",
      children: "$children.presentChild"
    }
  }
])

Legeplads




  1. Nulstilling af adgangskode i NodeJS

  2. OAuth 2.0 - Hvornår skal et adgangstoken fornyes med opdateringstoken?

  3. MongoDB db.copyDatabase fejler på uautoriseret

  4. Mongodb\BSON\Regex Php:Udfør Like Match