如何获取猫鼬数据的分层嵌套对象



我有这样的数据:

[{ "id": 80, "Category": "1", "sub_category": null},
{ "id": 81, "Category": "1.1", "sub_category": 80},
{ "id": 82, "Category": "1.1.1", "sub_category": 81},
{ "id": 83, "Category": "1.2", "sub_category": 80},
{ "id": 84, "Category": "1.1.1.1", "sub_category": 82}]

我正在使用带有猫鼬的Express JS。 节点版本10.19.0和npm版本6.14.9以及Express JS版本4.17.1。 我有一个类别表,我必须获取具有分层嵌套数据的数据。 喜欢这个

{ "id": 80, 
"Category": "1", 
"sub_category": null, 
"SubCategories": [{ "id": 81, 
"Category": "1.1", 
"sub_category": 80,
"SubCategories": [{ "id": 82, 
"Category": "1.1.1", 
"sub_category": 81,
"SubCategories": [{ "id": 84, 
"Category": "1.1.1.1", 
"sub_category": 82,
"SubCategories": [...]
},]
},]
},
{ "id": 83, 
"Category": "1.2", 
"sub_category": 80,
"SubCategories": [...]
},]
}

我尝试了图形查找查询,

CategoryModel.aggregate([{
$graphLookup: {
from: "examcategories", 
startWith: "$id", 
connectFromField: "id", 
connectToField: "sub_category", 
as: "SubCategoies" 
} 
}])

并获得这样的输出

{ 
"id": 80, 
"Category": "1", 
"sub_category": null,
"SubCategories": [{ 
"id": 81,
"Category": "1.1",
"sub_category": 80 
},{ 
"id": 82,
"Category":"1.1.1",
"sub_category": 81 
},{ 
"id": 84,
"Category": "1.1.1.1",
"sub_category": 82 
},{ 
"id": 83,
"Category": "1.2",
"sub_category": 80,
}
]}

$graphLookup对集合执行递归搜索,具有通过递归深度和查询过滤器限制搜索的选项,但$groupLookup还不够,需要使用更多运算符

  • $match记录只有sub_category的筛选器是null
  • $graphLookup获取子类别记录和深度编号 defthFieldlevel
  • $unwind解构数组SubCategories并允许不删除空的子类别
  • 按深度级别场level降序$sort
  • 通过id字段$group并重建SubCategories数组
CategoryModel.aggregate([
{ $match: { sub_category: null } },
{
$graphLookup: {
from: "examcategories",
startWith: "$id",
connectFromField: "id",
connectToField: "sub_category",
depthField: "level",
as: "SubCategories"
}
},
{
$unwind: {
path: "$SubCategories",
preserveNullAndEmptyArrays: true
}
},
{ $sort: { "SubCategories.level": -1 } },
{
$group: {
_id: "$id",
sub_category: { $first: "$sub_category" },
Category: { $first: "$Category" },
SubCategories: { $push: "$SubCategories" }
}
},
  • $addFields现在找到嵌套的级别子类别并分配到其级别,
    • $reduce迭代SubCategories数组的循环。
    • 初始化默认字段level默认值为 -1,presentChild为 [],prevChild为 [] 用于条件目的
    • $let初始化字段:
      • prev根据条件,如果两个level相等,则返回prevChild否则返回presentChild
      • current根据条件,如果两个level相等,则返回presentChild否则 []
    • in从初始化的字段中返回level字段和prevChild字段
      • 从数组prevpresentChild$filterSubCategories并返回,使用$mergeObjects将当前对象与数组合并SubCategories并使用$concatArrays与 let 数组current连接
  • $addFields只返回presentChild数组,因为我们只需要处理过的数组
{
$addFields: {
SubCategories: {
$reduce: {
input: "$SubCategories",
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",
{
SubCategories: {
$filter: {
input: "$$prev",
as: "e",
cond: { $eq: ["$$e.sub_category", "$$this.id"] }
}
}
}
]
}
]
]
}
}
}
}
}
}
}
},
{ $addFields: { SubCategories: "$SubCategories.presentChild" } }
])

操场

<小时 />

不含$mergeObjects: 操场

最新更新