如何获取猫鼬数据的分层嵌套对象
How to Get hierarchical nested object of mongoose data
我有这样的数据:
[{ "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。
我有一个类别 table,我必须获取具有分层嵌套数据的数据。
像这样
{ "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,
}
]}
$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
相等则 return prevChild
否则 return presentChild
current
根据条件如果两个 level
相等则 return presentChild
否则 []
in
到 return level
字段和初始化字段中的 prevChild
字段
presentChild
$filter
SubCategories
来自 prev
数组和 return,使用 $mergeObjects
将当前对象与 SubCategories
数组合并并使用 $concatArrays
与 let 的 current
数组连接
$addFields
到 return 只有 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
:
Playground
我有这样的数据:
[{ "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。 我有一个类别 table,我必须获取具有分层嵌套数据的数据。 像这样
{ "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,
}
]}
$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
相等则 returnprevChild
否则 returnpresentChild
current
根据条件如果两个level
相等则 returnpresentChild
否则 []
in
到 returnlevel
字段和初始化字段中的prevChild
字段presentChild
$filter
SubCategories
来自prev
数组和 return,使用$mergeObjects
将当前对象与SubCategories
数组合并并使用$concatArrays
与 let 的
current
数组连接
$addFields
到 return 只有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
:
Playground