gpt4 book ai didi

Mongodb 递归查询与 $graphLookup 不按预期工作

转载 作者:行者123 更新时间:2023-12-03 18:49:29 25 4
gpt4 key购买 nike

在我的文档中,我有 _id、一个 companyName 和一个赞助商(通过 _id 标识父文档)。
例如,我有第一条没有赞助商( parent )的记录

_id:607536219910ef23e80e0bbe
companyname:"Main Company"
sponsor:"
然后是公司 1,其中主要公司是母公司:
  _id:607e16760a9d2c16e06bc252
companyname:"Company 1"
sponsor:"607536219910ef23e80e0bbe"
以及公司 2,其中公司 1 是母公司:
_id:607e187b0a9d2c16e06bc253
companyname:"Company 2"
sponsor:"607e16760a9d2c16e06bc252"
以及公司 3,其中公司 2 是母公司:
_id:607e1f470a9d2c16e06bc254
companyname:"Company 3"
sponsor:"607e187b0a9d2c16e06bc253"
我做了一个 $match 来为主要公司带来 children 的记录
{
sponsor: '607536219910ef23e80e0bbe'
}
然后我 $addFields userid,这是一个 _Id 转换为字符串。这是稍后与赞助商匹配:
{"userid": { "$toString": "$_id" }}
现在,当我使用 graphLookup 时,我得到 Main Company 的子公司(Company 2),但我没有将 Company 3 作为 Company 2 的 child。我只得到 Company 1 和 Company 2:
enter image description here
这是我的图表查找
{
from: 'pls',
startWith: "$userid",
connectFromField: 'userid',
connectToField: 'sponsor',
as: 'downline',
maxDepth: 100,
restrictSearchWithMatch: {}
}
任何帮助将不胜感激。
更新:
正如 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"
}
TURIVISHAL 的解决方案:
根据 Turivishal 解决方案,这是最终的流水线,它提供了重复查询的完美下线/层次结构/ TreeView ,并与 Angular Treeview 控件完美配合。非常感谢 Turivishal。我相信你应该发布一个答案,这样我才能接受它并且它对其他人有用。
他的解决方案与他提出的解决方案非常相似,但要好得多。我最终创建了一个名为 PLID 的新字段,它复制了 _id 字段,并且效果非常好。我让管理员决定他们是否认为这个问题应该结束,因为 Turivishal 解决方案同样基于那个 Q,但在我看来更清楚。这是他的作品:
[
{
'$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'
}
}
]

最佳答案

您可以使用 $graphLookup和其他有用的数组运算符,

  • $match过滤记录只有 sponsor""
  • $graphLookup获取depthField level中的子记录和深度编号
  • $unwind解构 downline数组并允许不删除空子项
  • $sort按深度级别字段 level按降序排列
  • $group来自 id场和重建downline阵列
  • $addFields现在找到嵌套级别的 child 并分配给它的级别,
  • $reduce迭代 downline 的循环大批。
  • 初始化默认字段 level默认值为 -1,presentChild是 [], prevChild是 [] 用于条件目的
  • $let初始化字段:
  • prev根据条件,如果两者都是 level相等则返回 prevChild否则返回 presentChild
  • current根据条件,如果两者都是 level相等则返回 presentChild否则 []

  • in返回 level场和 prevChild来自初始化字段的字段
  • presentChild $filter downline来自 prev数组并返回,将当前对象与 downline 合并数组使用 $mergeObjects并与 current 连接使用 $concatArrays 的 let 数组


  • $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" } }
    ])
    Playground

    关于Mongodb 递归查询与 $graphLookup 不按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67170965/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com