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

Ottenere antenati in MongoDb usando la struttura ad albero

È non-trivial soluzione.

REQUISITI

1 Abbiamo bisogno di aggiungere un campo extra (chiamiamolo level ) che indica dove si trova il documento all'interno della gerarchia.

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

2 Abbiamo bisogno di define precedentemente la profondità della gerarchia (ad esempio:max 3)

LIMITAZIONE

Per filtrare da un livello specifico, dobbiamo modificare root e children $corrispondenza valori.

Assicurati sempre il livello gerarchico:

root     - 0
children - 1

root     - 1
children - 2  

SOLUZIONE

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 (profondità massima:3) | MongoPlayground (profondità massima:4)

SPIEGAZIONE

  1. Con $facet definiamo la struttura dei livelli. root solo tutta la directory principale. children contiene tutti i bambini con discendenti di livello 1 + figli.

  2. $filter (unire) root e figli tramite parentId

  3. Con $project e $replaceRoot restituiamo la struttura originale.

LINK

https://docs.mongodb.com/manual/reference/operator/ aggregazione/sfaccettatura/
https://docs.mongodb.com/manual/ riferimento/operatore/aggregazione/filtro/
https://docs.mongodb.com/manual/ riferimento/operatore/aggregazione/replaceRoot/