Mongodb:在graphlookup中计算connectToField [英] Mongodb: calculated connectToField inside graphlookup

查看:16
本文介绍了Mongodb:在graphlookup中计算connectToField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有如下所示的 mongo 树结构:

I have mongo tree structure that looks like this:

{"parent": null, "path": "#a", "name": "a"}
{"parent": "a", "path": "#a#b", "name": "b"}
{"parent": "a", "path": "#a#c", "name": "c"}
{"parent": "b", "path": "#a#b#1", "name": "1"}
{"parent": "b", "path": "#a#b#2", "name": "2"}
{"parent": "c", "path": "#a#c#1", "name": "1"}
{"parent": "1", "path": "#a#c#1#x", "name": "x"}

可以表示为:

#a
|_#a#b
|    |_#a#b#1
|    |_#a#b#2
|_#a#c
    |_#a#c#1
          |_#a#c#1#x

我的目标是构建一个请求,只获取指定节点下的叶子.

My goal is to build a request that will get only the leaves under a specified node.

如果我将父路径存储在字段 parent 而不是父标识符中,我将能够使用以下请求来做到这一点:

Had I stored the parent path inside the field parent instead of the parent identifier I would have been able to do it using the following request:

db.tree.aggregate([
        {$match:{"parent": {$regex:"^#a#c"}}}, 
        {$graphLookup:{
                       from:"tree", 
                       startWith:"$path", 
                       connectFromField:"path", 
                       connectToField:"parent", 
                       as:"dep"}}, 
        {$match:{dep:[]}}, 
        {$project:{"_id":0, path:1}}
])

正如我在上一个问题中已经回答的那样:Mongodb:只获取树叶

as already answered in my previous question here: Mongodb: get only leaves of tree

问题是我没有.

所以我必须以某种方式转换我请求中的connectToField",以便它代表我父母的路径而不是我父母的 id.有没有人知道如何做到这一点?

So I have to somehow transform the 'connectToField' in my request so that it represents the path of my parent instead of the id of my parent. Does anybody have an idea on how to do this?

推荐答案

connectToField 是一个名称,而不是一个表达式.你不能用它做任何事情.

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: [] } },                       
])

这篇关于Mongodb:在graphlookup中计算connectToField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆