Mongodb:在将其用作聚合中的 connectFromField 之前计算一个值 [英] Mongodb: compute a value before using it as connectFromField in an aggregate

查看:61
本文介绍了Mongodb:在将其用作聚合中的 connectFromField 之前计算一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have mongo tree structure that looks like this:

{"_id":uid1,"parent": null, "path": "#uid1", "name": "a"}
{"_id":uid2,"parent": "uid1", "path": "#uid1#uid2", "name": "b"}
{"_id":uid3,"parent": "uid1", "path": "#uid1#uid3", "name": "c"}
{"_id":uid4,"parent": "uid2", "path": "#uid1#uid2#uid4", "name": "1"}
{"_id":uid5,"parent": "uid2", "path": "#uid1#uid2#uid5", "name": "2"}
{"_id":uid6,"parent": "uid1", "path": "#uid1#uid6", "name": "1"}
{"_id":uid7,"parent": "uid6", "path": "#uid1#uid6#uid7", "name": "x"}

其中每个节点都由其唯一 id uidx 表示,并通过其父节点的 uid 定位.每次节点的父节点修改其路径时,其子节点的路径都会自动修改(在 mongoose 预保存中).

where every node is represented by its unique id uidx and located thanks to its parent's uid. Everytime the parent of a node is modified its path and the paths of its children are automatically modified (inside a mongoose pre-save).

上面的例子可以表示如下:

The example above can be represented as follows:

a
|_b
|    |_1
|    |_2
|_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 only the parent identifier I would have been able to do it using the following request:

db.tree.aggregate([
        {$match:{"parent": {$regex:"^#uid1#uid2"}}}, 
        {$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?

这个问题是我上一个问题的重写版本:以前的版本

This question is a rewritten version of my previous question here:previous version

推荐答案

你不需要计算任何东西,也不需要依赖 path.这是 https://docs.mongodb.com/manual 中的确切用例/reference/operator/aggregation/graphLookup/.{ $match: { dep: [] } } 阶段返回没有子节点的节点,即叶子节点.

You don't need to calculate anything, nor rely on the path. It is the exact usecase from https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/. The { $match: { dep: [] } } stage returns nodes with no children, i.e. leaves.

db.tree.aggregate([
    { $graphLookup: {
        from:"tree", 
        startWith:"$_id", 
        connectFromField:"_id", 
        connectToField:"parent", 
        as:"dep",
        maxDepth: 1
    } },
    { $match: { dep: [] } },                       
])

添加

maxDepth: 1 以加快速度.只要节点有直接子节点,您就不必关心分支的其余部分,因此直接子节点的 1 级深度就足够了:

maxDepth: 1 is added to speed things up a bit. As soon as the node have a direct child you don't care about rest of the branch, so 1 level depth for direct children is sufficient:

这篇关于Mongodb:在将其用作聚合中的 connectFromField 之前计算一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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