在我的文档中,我有 _id、公司名称和赞助商(通过 _id 标识父文档)。
例如,我有第一条没有赞助商(父母)的记录
_id:607536219910ef23e80e0bbe
companyname:"Main Company"
sponsor:"
Run Code Online (Sandbox Code Playgroud)
然后是公司 1,其中主公司是母公司:
_id:607e16760a9d2c16e06bc252
companyname:"Company 1"
sponsor:"607536219910ef23e80e0bbe"
Run Code Online (Sandbox Code Playgroud)
公司 2,其中公司 1 是母公司:
_id:607e187b0a9d2c16e06bc253
companyname:"Company 2"
sponsor:"607e16760a9d2c16e06bc252"
Run Code Online (Sandbox Code Playgroud)
公司 3,其中公司 2 是母公司:
_id:607e1f470a9d2c16e06bc254
companyname:"Company 3"
sponsor:"607e187b0a9d2c16e06bc253"
Run Code Online (Sandbox Code Playgroud)
我正在做一场$match来为主要公司带来孩子们的记录
{
sponsor: '607536219910ef23e80e0bbe'
}
Run Code Online (Sandbox Code Playgroud)
然后我 $addFields userid,这是一个转换为字符串的 _Id。这是稍后与赞助商匹配的:
{"userid": { "$toString": "$_id" }}
Run Code Online (Sandbox Code Playgroud)
现在,当我 graphLookup 时,我得到了主公司的子公司(公司 2),但我没有得到公司 3 作为公司 2 的子公司。我只得到了公司 1 和公司 2:
这是我的 graphLookup
{
from: 'pls',
startWith: "$userid",
connectFromField: 'userid',
connectToField: 'sponsor',
as: 'downline',
maxDepth: 100,
restrictSearchWithMatch: {}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。
更新:
正如 Turivishal 下面所说,查询有效,但这些是我期望的结果:
[{
"_id": "607536219910ef23e80e0bbe",
"companyname": "Main Company",
"downline": [{
"_id": "607e16760a9d2c16e06bc252",
"companyname": "Company 1",
"sponsor": "607536219910ef23e80e0bbe",
"downline": [{
"_id": "607e187b0a9d2c16e06bc253",
"companyname": "Company 2",
"sponsor": "607e16760a9d2c16e06bc252",
"downline": [{
"_id": "607e1f470a9d2c16e06bc254",
"companyname": "Company 3",
"sponsor": "607e187b0a9d2c16e06bc253"
}]
}]
}],
"sponsor": "",
"userId": "607536219910ef23e80e0bbe"
}
Run Code Online (Sandbox Code Playgroud)
Turivishal 的解决方案:
根据 Turivishal 解决方案,这是最终的管道,它提供了循环查询的完美下线/层次结构/树视图,并且与 Angular Treeview 控件完美配合。非常感谢图里维沙尔。我相信您应该发布一个答案,以便我可以接受它并且对其他人有用。
他的解决方案与他提出的解决方案非常相似,但要好得多。我最终创建了一个名为 PLID 的新字段,它复制了 _id 字段,并且效果非常好。我让管理员决定他们是否认为应该关闭这个问题,因为图里维沙尔解决方案再次基于该问题,但在我看来更清晰。这是他的作品:
[
{
'$match': {
'sponsor': '0'
}
}, {
'$graphLookup': {
'from': 'pls',
'startWith': '$plid',
'connectFromField': 'plid',
'connectToField': 'sponsor',
'depthField': 'level',
'as': 'children'
}
}, {
'$unwind': {
'path': '$children',
'preserveNullAndEmptyArrays': true
}
}, {
'$sort': {
'children.level': -1
}
}, {
'$group': {
'_id': '$plid',
'sponsor': {
'$first': '$sponsor'
},
'companyname': {
'$first': '$companyname'
},
'children': {
'$push': '$children'
}
}
}, {
'$addFields': {
'children': {
'$reduce': {
'input': '$children',
'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', {
'children': {
'$filter': {
'input': '$$prev',
'as': 'e',
'cond': {
'$eq': [
'$$e.sponsor', '$$this.plid'
]
}
}
}
}
]
}
]
]
}
}
}
}
}
}
}
}, {
'$addFields': {
'children': '$children.presentChild'
}
}
]
Run Code Online (Sandbox Code Playgroud)
您可以使用$graphLookup和其他有用的数组运算符,
$match
记录仅有的过滤器sponsor
是""
$graphLookup
获取深度字段中的子记录和深度编号level
$unwind
解构downline
数组并允许不删除空子数组$sort
按深度级别字段level
降序排列$group
按id
字段并重建downline
数组$addFields
现在找到嵌套的级别子级并分配给其级别,
$reduce
迭代downline
数组的循环。level
默认值为-1,presentChild
is[],prevChild
is[]用于条件目的$let
初始化字段:
prev
根据条件如果两者level
相等则返回prevChild
否则返回presentChild
current
根据条件,如果两者level
相等,则返回,presentChild
否则返回 []in
从初始化字段
返回level
字段和字段prevChild
presentChild
$filter
downline
from prev
array 并返回,将当前对象与downline
数组 using合并,并与let using 的数组$mergeObjects
连接current
$concatArrays
$addFields
仅返回presentChild
数组,因为我们只需要处理后的数组db.collection.aggregate([
{ $match: { sponsor: "" } },
{
$graphLookup: {
from: "collection",
startWith: "$_id",
connectFromField: "_id",
connectToField: "sponsor",
depthField: "level",
as: "downline"
}
},
{
$unwind: {
path: "$downline",
preserveNullAndEmptyArrays: true
}
},
{ $sort: { "downline.level": -1 } },
{
$group: {
_id: "$_id",
sponsor: { $first: "$sponsor" },
companyname: { $first: "$companyname" },
downline: { $push: "$downline" }
}
},
{
$addFields: {
downline: {
$reduce: {
input: "$downline",
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",
{
downline: {
$filter: {
input: "$$prev",
as: "e",
cond: { $eq: ["$$e.sponsor", "$$this._id"] }
}
}
}
]
}
]
]
}
}
}
}
}
}
}
},
{ $addFields: { downline: "$downline.presentChild" } }
])
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1575 次 |
最近记录: |