【问题标题】:MongoDB Storing deeply nested tree - How to query nested document?MongoDB 存储深度嵌套树 - 如何查询嵌套文档?
【发布时间】:2013-09-19 02:42:22
【问题描述】:

我正在尝试构建一个架构来存储网站导航地图。将典型的数据集想象成一个站点地图,其中页面可以有子页面,而这些子页面可以有更多的子页面。一个例子是以下对象:

$tree = array(
    'home' => array(
        'h1' => 'test',
        'h2' => 'test2',
        'copy' => 'copy here',
        'slug' => '',
        'children' => array(
            'blah' => array(
                'h1' => 'child1',
                'h2' => 'child1',
                'copy' => 'child copy here',
                'slug' => 'blah',
                'children' => array(
                    'blahsub' => array(
                        'h1' => 'subchild1',
                        'h2' => 'subchild2',
                        'copy' => 'child copy here',
                        'slug' => 'blahsub',
                        'children' => array(
                            'subsubchild1' => array(
                                'h1' => 'subsubchild1',
                                'h2' => 'subsubchild2',
                                'copy' => 'child copy here',
                                'slug' => 'subsubchild1'
                            )
                        )
                    ),
                    'subchild2' => array(
                        'h1' => 'subchild1',
                        'h2' => 'subchild2',
                        'copy' => 'child copy here',
                        'slug' => 'subchild2',
                        'children' => array(
                            'subsubchild2' => array(
                                'h1' => 'subsubchild1',
                                'h2' => 'subsubchild2',
                                'copy' => 'child copy here',
                                'slug' => 'subsubchild2'
                            )
                        )
                    ),
                    'subchild3' => array(
                        'h1' => 'subchild1',
                        'h2' => 'subchild2',
                        'copy' => 'child copy here',
                        'slug' => 'subchild3',
                        'children' => array(
                            'subsubchild3' => array(
                                'h1' => 'subsubchild1',
                                'h2' => 'subsubchild2',
                                'copy' => 'child copy here',
                                'slug' => 'subsubchild3'
                            )
                        )
                    )
                )
            ),
            'another' => array(
                'h1' => 'child2',
                'h2' => 'child2',
                'copy' => 'child copy here',
                'slug' => 'another'
            )
        )
    )
);

$tree 的每一层都由它的 URI 来索引,每一层可以包含 N 个子节点,每个子节点都可以有自己的子节点。

我最初的想法是使用这个模式很直观,但是我不确定查询树的特定节点。我接近这个模式错了吗? (目标是不必进行多次查询以在每个请求上“构建”这样的树,而是将其拉一次并在内存中使用它。

注意:我仍然可以进行查询以拉取整个树,然后通过下标运算符直接访问每个节点。这应该比对树的多个查询提供更好的性能。目前为此使用 mysql,这是一个真正的瓶颈。

请分享您对此架构的看法,如果有不清楚的地方,请要求澄清。

谢谢!

注意 - 主要目标:我想通过它们的“索引”(也是每个节点的“slug”参数)在树中查找项目。我真的不知道从哪里开始——这样的查询功能是否存在?必须在多个查询的循环中完成吗?

【问题讨论】:

  • 如果它是/曾经是瓶颈,您可能需要考虑缓存以前获取的结果。
  • 你想做什么?只获取嵌套元素的一部分?展示您尝试过的内容会有所帮助。
  • 我想通过它们的“索引”(也是每个节点的“slug”参数)在树中查找项目。我真的不知道从哪里开始——这样的查询功能是否存在?必须在多个查询的循环中完成吗?

标签: php mongodb tree mongodb-query


【解决方案1】:

此架构不适合查询和更新。例如,您不能更新 subsubchild3 来保证不会出现竞争条件或更新过时的文档。

关于查询,目前唯一可以想到的方法是使用聚合框架,我相信。

您应该查看此页面:http://docs.mongodb.org/manual/tutorial/model-tree-structures/,了解如何在 MongoDB 手册中对树结构进行建模,更具体地说是“物化路径”。在查询方面,我发现该方法取得了成功,但是,它更难更新,您只需要权衡您的选项并选择最适合您的查询的方法。

【讨论】:

  • 我对使用物化路径模式犹豫不决的原因是对父节点路径的修改不会“涓涓细流”树。例如,/programming & /programming/ruby。如果要将“编程”更改为“程序”,您将被 /programs 和 /programming/ruby 卡住。从“读取”的角度来看,我喜欢我提出的树,因为它是从数据库中使用的单个对象,但是您对执行对特定节点的写入有任何见解吗?另外,你能详细说明一下你提到的比赛案例吗?谢谢!
  • @user2107642 这是物化路径有问题的地方,你必须更新所有子节点,尽管我实际上已经在两个调用中让它工作,一个更新父节点,下一个更新子节点
  • @user2107642 与比赛情况会发生,因为位置运算符和什么不能只能深入 2 并且仅匹配目前找到的第一个(我认为嵌套 $ 数学将在 2.5 中出现)这意味着为了有效地更新孩子,您需要将文档拉出,修改然后将其保存回来,这可能会导致您更新过时的文档
  • @user2107642 本质上,您对本文档的操作很有可能不是原子操作
猜你喜欢
  • 1970-01-01
  • 2018-03-09
  • 2021-02-25
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多