sql >> Databasteknik >  >> NoSQL >> MongoDB

Få förfäder i MongoDb med hjälp av trädstruktur

Det är non-trivial lösning.

KRAV

1 Vi måste lägga till extra fält (låt oss kalla det level ) som indikerar var dokumentet finns i hierarkin.

|root        0
|-child A    1
|--child A_1 2
|-child B    1

2 Vi måste define tidigare hierarkidjup (till exempel:max 3)

BEGRÄNSNING

För att filtrera från specifik nivå måste vi ändra root och children $match värden.

Säkerställ alltid hierarkinivå:

root     - 0
children - 1

root     - 1
children - 2  

LÖSNING

db.documents.aggregate([
  {
    $facet: {
      root: [
        {
          $match: {
            level: 0
          }
        }
      ],
      children: [
        {
          $match: {
            level: 1
          }
        },
        {
          $graphLookup: {
            from: "documents",
            startWith: "$_id",
            connectFromField: "_id",
            connectToField: "parentId",
            maxDepth: 0,
            as: "hierarchy"
          }
        },
        {
          $sort: {
            _id: 1
          }
        }
      ]
    }
  },
  {
    $unwind: "$root"
  },
  {
    $project: {
      "root._id": 1,
      "root.name": 1,
      "root.level": 1,
      "root.hierarchy": {
        $filter: {
          input: "$children",
          as: "sub_level",
          cond: {
            $eq: [
              "$$sub_level.parentId",
              "$root._id"
            ]
          }
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: "$root"
    }
  }
])

MongoPlayground (max djup:3) | MongoPlayground (max djup:4)

FÖRKLARING

  1. Med $facet vi definierar nivåstruktur. root endast alla rotkataloger. children innehåller alla barn med nivå 1 + barn ättlingar.

  2. Vi $filter (sammanfoga) root och underordnade av parentId

  3. Med $project och $replaceRoot vi returnerar den ursprungliga strukturen.

LÄNKAR

https://docs.mongodb.com/manual/reference/operator/ aggregation/facet/
https://docs.mongodb.com/manual/ referens/operatör/aggregation/filter/
https://docs.mongodb.com/manual/ referens/operatör/aggregation/replaceRoot/




  1. $unset är tom. Du måste ange ett fält så här:{$unset:{<field>:...}}

  2. Populera på grundval av tillstånd i mongoose, mongoDB

  3. MongoDB:Antal matchande kapslade arrayelement

  4. Pymongo returnerar endast värden som lista