Mongodb: calculated connectToField inside graphlookup

前端 未结 1 1479
说谎
说谎 2021-01-27 07:10

I have mongo tree structure that looks like this:

{\"parent\": null, \"path\": \"#a\", \"name\": \"a\"}
{\"parent\": \"a\", \"path\": \"#a#b\", \"name\": \"b\"}
         


        
相关标签:
1条回答
  • 2021-01-27 08:03

    connectToField is a name, not an expression. You can't do anything with it.

    You really need to re-consider the schema. It is flawed in many ways starting from non-unique names used in parent references. Since you rely on the path string instead (which is a questionable decision by itself), you need a path to reference the parent.

    The answer below does it runtime, and is hardly advisable for operational queries due to performance inefficiency and some assumptions of how the path is built. It can be used as a one-off request though.

    Basically you need to create a view with calculated parent path:

    db.createView("rootless_tree", "tree", [
        { $match: { parent: { $ne: null } } },
        { $addFields: {
            parent_path: { $let: {
                vars: { parents: { $split: [ "$path", "#" ] } },
                in: { $reduce: {
                    input: { $slice: [ "$$parents", 1, { $subtract: [ { $size: "$$parents" }, 2 ] } ] },
                    initialValue: "",
                    in: { $concat: [ "$$value", "#", "$$this" ] }
                } }
            } }
        } }
    ]);
    

    So then you can do your lookup as advised in your previous question:

    db.tree.aggregate([
        { $graphLookup: {
            from: "rootless_tree", 
            startWith: "$path", 
            connectFromField: "path", 
            connectToField: "parent_path", 
            as:"dep"
        } },
        { $match: { dep: [] } },                       
    ])
    
    0 讨论(0)
提交回复
热议问题