我有这样的数据:
[{ "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。 node 版本 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": [...]
},]
}
我为此尝试了 graphLookup 查询,
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,
}
]}
答案 0 :(得分:0)
$graphLookup 对集合执行递归搜索,提供通过递归深度和查询过滤器限制搜索的选项,但仅 $groupLookup
还不够,需要使用更多运算符
$match
过滤器只有 sub_category
的记录是 null
$graphLookup
获取 defthField level
$unwind
解构 SubCategories
数组并允许不删除空子类别$sort
按深度级别字段 level
降序排列$group
通过 id
字段并重建 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
字段
presentChild
$filter
SubCategories
来自 prev
数组并返回,使用 SubCategories
将当前对象与 $mergeObjects
数组合并,并使用 {{1} 连接}} let 数组使用 current
$concatArrays
只返回 $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" } }
])
:
Playground