加入 $graphLookup 结果与其他集合

Join $graphLookup result with other collection

我正在研究存储二叉树的层次结构。 假设我有两个集合:用户和节点。 用户集合存储个人信息,节点使用 Parent 引用模式存储树结构:https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-parent-references/

用户:

[{
  "_id": {
    "$oid": "600365521599912a5c814e5e"
  },
  "nombre": "Andres",
  "correo": "oachica@gmail.com"
},{
  "_id": {
    "$oid": "600365e9ccf1e51b2cab341f"
  },
  "nombre": "Andres",
  "correo": "cachi777_@hotmail.com"
},{
  "_id": {
    "$oid": "6004591536a40941f48121f9"
  },
  "nombre": "Laura",
  "correo": "w.l777@hotmail.com"
},{
  "_id": {
    "$oid": "6004596936a40941f48121fb"
  },
  "nombre": "Javi",
  "correo": "jocta@hotmail.com"
},{
  "_id": {
    "$oid": "60047cf23f3f1a0d647cb2c7"
  },
  "nombre": "Lina",
  "correo": "lvelas@hotmail.com"
}]

节点:

[{
  "_id": {
    "$oid": "60035d0a1599912a5c814e58"
  },
  "idUsuario": "600365521599912a5c814e5e",
  "nodoPadre": ""
},{
  "_id": {
    "$oid": "60047e6874cab54a7088ca56"
  },
  "idUsuario": "600365e9ccf1e51b2cab341f",
  "nodoPadre": {
    "$oid": "60035d0a1599912a5c814e58"
  }
},{
  "_id": {
    "$oid": "60047f42c89add3c20cff990"
  },
  "idUsuario": "6004591536a40941f48121f9",
  "nodoPadre": {
    "$oid": "60047e6874cab54a7088ca56"
  }
},{
  "_id": {
    "$oid": "60047f5dc89add3c20cff991"
  },
  "idUsuario": "6004596936a40941f48121fb",
  "nodoPadre": {
    "$oid": "60047f42c89add3c20cff990"
  }
},{
  "_id": {
    "$oid": "600480de9fd6a42b40679e6d"
  },
  "idUsuario": "60047cf23f3f1a0d647cb2c7",
  "nodoPadre": {
    "$oid": "60047f5dc89add3c20cff991"
  }
}]  

nodos中的每个文档在_id和idUsuario绑定的用户中都有对应的文档。

通常节点集合中的文档在同一集合中有一个 parent 节点,由 nodoPadre 字段绑定。

我可以使用 $graphLookup 聚合获得节点的 childs:

如你所见,我得到了一个节点的 childs。现在我需要将每个 child 中的个人信息放入结果数组“hijos”中,如下所示:

感谢您的帮助。

  • $graphLookup 根据您的要求
  • $unwind解构hijos数组
  • $addFieldshijos.idUsuario 转换为对象 ID,因为它是一个字符串,如果它已经在对象 ID 中,则删除此阶段
  • $lookupusers 集合
  • $unwind解构hijos.idUsuario数组
  • $addFields 删除 hijos 如果它是空白 {} object
  • $group 通过 _id 并重建 hijos 数组
db.nodes.aggregate([
  {
    "$graphLookup": {
      "from": "nodes",
      "startWith": "$_id",
      "connectFromField": "_id",
      "connectToField": "nodoPadre",
      "as": "hijos",
      "maxDepth": 4
    }
  },
  {
    $unwind: {
      path: "$hijos",
      preserveNullAndEmptyArrays: true
    }
  },
  { $addFields: { "hijos.idUsuario": { $toObjectId: "$hijos.idUsuario" } } },
  {
    "$lookup": {
      "from": "users",
      "localField": "hijos.idUsuario",
      "foreignField": "_id",
      "as": "hijos.idUsuario"
    }
  },
  {
    $unwind: {
      path: "$hijos.idUsuario",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $addFields: {
      hijos: {
        $cond: [{ $eq: ["$hijos", {}] }, "$$REMOVE", "$hijos"]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      hijos: { $push: "$hijos" },
      idUsuario: { $first: "$idUsuario" },
      nodoPadre: { $first: "$nodoPadre" }
    }
  }
])

Playground