最有效的方式来存储蒙戈嵌套类(或分层数据)?(Most efficient way to store

2019-08-17 01:51发布

我们已经嵌套类的一些产品(如体育- >篮球- >男子体育- >网球- >女性 )和正在使用的,而不是MySQL的蒙戈。

我们知道如何嵌套类存储在SQL数据库如MySQL,但希望在什么为蒙戈做任何意见。 我们需要优化的操作快速查找在一个类别或子类别所有的产品,它可以被嵌套低于根类别数层(例如,所有产品在男篮类别或全部产品在女子网球类)。

这蒙戈文档表明一个方法,但它说,需要为子树,这是我们需要(因为分类可以达到多个级别)操作时不能很好地工作。

在最好的办法任何建议,以有效地存储和搜索任意深度的嵌套类?

Answer 1:

要决定的第一件事正是你会用什么样的树。

要考虑的一件大事是您的数据和访问模式。 你已经说过,90%,所有的工作都将被查询,并通过它(电子商务)的声音更新将只有管理员才能运行,最有可能的很少。

所以,你想一个模式,让你的孩子快速查询的权力,通过一个路径,即:体育 - >篮球 - >男子,体育 - >网球 - >女性,而并不真正需要真正扩展到更新。

当你这样正确地指出MongoDB的确实有一个很好的文档页面: https://docs.mongodb.com/manual/applications/data-models-tree-structures/因此10gen的实际状态不同型号和树木的模式和方法介绍了主窗口和他们的起伏。

应该赶上如果你正在寻找方便地查询眼睛的一个物化的路径: https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-materialized-paths/

这是一个非常有趣的建立树木,因为对你在“网球”上面给了成“妇女”这个例子查询方法,你可以简单地做一个预先确定的正则表达式(可以使用索引: HTTP://docs.mongodb .ORG /手动/参考/运营商/正则表达式/ ),如下所示:

db.products.find({category: /^Sports,Tennis,Womens[,]/})

找到在你的树的某个路径中列出的所有产品。

不幸的是这种模式是在更新真的不好,如果你移动一个类别或更改其名称必须更新的所有产品,并有可能是成千上万的产品在一个类别下。

更好的方法是容纳cat_id在产品上,然后将类别分成与架构独立的集合:

{
    _id: ObjectId(),
    name: 'Women\'s',
    path: 'Sports,Tennis,Womens',
    normed_name: 'all_special_chars_and_spaces_and_case_senstive_letters_taken_out_like_this'
}

所以,现在你的查询只涉及分类收集这将使他们更小和更高性能。 唯一的例外是当你删除一个类别,产品仍然需要感动。

因此,改变“网球”到“巴德明”的例子:

db.categories.update({path:/^Sports,Tennis[,]/}).forEach(function(doc){
    doc.path = doc.path.replace(/,Tennis/, ",Badmin");
    db.categories.save(doc);
});

不幸的MongoDB目前没有提供在查询文档反射,这样你就不得不拉出来的客户端这是一个有点讨厌,但是希望它不应导致被带到种类太多了。

这基本上是它是如何工作真的。 这是一个有点疼痛的更新却可以即时查询使用索引的任何路径上的功率是为您的方案,我相信更多的配件。

当然,好处是,这个模式是嵌套集模型兼容: http://en.wikipedia.org/wiki/Nested_set_model我发现一次又一次只是真棒电子商务网站,例如,网球可能是下两个“体育”和“休闲”,并且希望根据用户来自哪里多条路径。

物化路径的模式只需添加另一个很容易支持该path ,就这么简单。

希望这是有道理的,相当长的一个人也没有。



Answer 2:

如果所有的类别是不同的,然后把它们看成标签。 层次结构是没有必要的物品编码,因为您在查询商品,不需要他们。 该层次是一个表象的东西。 与所有的类别标签中的每个项目在它的路径,所以“体育>棒球>鞋”可以保存为{..., categories: ["sport", "baseball", "shoes"], ...} 如果你想在“运动”类别中的所有项目,搜索{categories: "sport"}如果你只想要鞋子,搜索{tags: "shoes"}

这不捕捉层次,但如果你仔细想想,这并不重要。 如果类是不同的,层次不帮你,当你查询的项目。 不会有其他的“棒球”,所以,当你搜索,你将只能得到低于该层次中的“棒球”层次的东西。

我的建议是依赖于类别,并且不同的,我想他们是不是在你的当前模型。 然而,没有任何理由,为什么你不能让他们截然不同。 你可能选择使用你的页面作为数据库中的类别名称上显示的字符串。 如果改为使用符号的名称,如“运动”或“womens_shoes”,并使用查找表来查找字符串显示在页面上(这也将节省您的工作时间,如果一个类别的名称都没有改变 - 它会做翻译的网站更容易,如果你会需要这样做),你可以很容易地确保它们是不同的,因为他们没有什么做什么是显示在页面上。 所以,如果你有两个“鞋”的层次结构(例如“网球>女士>鞋”和“网球>男装>鞋”),你可以再补充一个限定词,使它们不同(例如“womens_shoes”和“mens_shoes”或“tennis_womens_shoes”)的符号名是任意的,可以是任何东西,你甚至可以使用数字,只是每次添加一个类别时使用的序列中的一个数字。



文章来源: Most efficient way to store nested categories (or hierarchical data) in Mongo?