在 Mongo 中存储嵌套类别(或分层数据)的最有效方法?

2024-01-07

我们为多种产品提供了嵌套类别(例如,体育 -> 篮球 -> 男子, 体育 -> 网球 -> 女子)并使用 Mongo 而不是 MySQL。

我们知道如何在 MySQL 等 SQL 数据库中存储嵌套类别,但如果您能提供有关如何对 Mongo 执行操作的建议,我们将不胜感激。我们需要优化的操作是快速查找一个类别或子类别中的所有产品,这些产品可以嵌套在根类别下面的几层(例如,男子篮球类别或所有产品女子网球类别)。

这个 Mongo 文档 https://docs.mongodb.com/manual/applications/data-models-tree-structures/建议一种方法,但它说当需要对子树进行操作时,它效果不佳,而我们需要这种方法(因为类别可以达到多个级别)。

关于有效存储和搜索任意深度的嵌套类别的最佳方法有什么建议吗?


您要决定的第一件事就是您将使用哪种树。

需要考虑的最重要的事情是您的数据和访问模式。您已经说过,您所有工作的 90% 都将是查询,并且听起来(电子商务)更新将仅由管理员运行,很可能很少。

因此,您需要一个架构,使您能够通过路径(即:体育 -> 篮球 -> 男子、体育 -> 网球 -> 女子)快速查询子项,并且实际上不需要真正扩展以更新。

正如您正确指出的那样,MongoDB 确实有一个很好的文档页面:https://docs.mongodb.com/manual/applications/data-models-tree-structs/ https://docs.mongodb.com/manual/applications/data-models-tree-structures/10gen 实际上陈述了树的不同模型和模式方法,并描述了它们的主要优点和缺点。

如果您希望轻松查询,应该引起注意的是物化路径:https://docs.mongodb.com/manual/tutorial/model-tree-structs-with-materialized-paths/ https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-materialized-paths/

这是一种非常有趣的构建树的方法,因为要查询上面给出的“网球”中“女性”的示例,您可以简单地执行一个预先固定的正则表达式(可以使用索引:http://docs.mongodb.org/manual/reference/operator/regex/ http://docs.mongodb.org/manual/reference/operator/regex/)像这样:

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 http://en.wikipedia.org/wiki/Nested_set_model我一次又一次地发现这对于电子商务网站来说非常棒,例如,网球可能同时位于“体育”和“休闲”下,并且您需要根据用户来自哪里的多个路径。

物化路径的模式只需添加另一个即可轻松支持这一点path,就这么简单。

希望它有意义,那里很长。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Mongo 中存储嵌套类别(或分层数据)的最有效方法? 的相关文章

  • 将日期差转换为年数以计算 MongoDB 中的年龄

    我正在使用以下方法来计算时间戳差异中的年龄 db getCollection person aggregate project item 1 DOB personal DOB dateDifference subtract new Date
  • Android中不同线程的数据库访问

    我有一个在 AsyncTasks 中从互联网下载数据的服务 它解析数据并将其存储在数据库中 该服务持续运行 当服务写入数据库时 活动会尝试从数据库中读取更改 我有一个数据库助手 有多种写入和读取方法 这会导致问题吗 可能尝试从两个不同的线程
  • 可以重复应用并产生相同结果的数据库操作吗?

    我现在一片空白 或者像有些人说的那样 正在经历一个高级时刻 我知道这个概念有一个正式的定义和名称 其中在数据库中运行的数据库操作 存储过程 如果重复运行将产生相同的结果 它属于数学家的自反 对称 传递等类型 您的意思是 确定性 吗 如果使用
  • pymongo复制辅助读取引用不起作用

    我们有 MongoDB 2 6 和 2 副本集 并且我们使用pymongo驱动程序并使用以下 url 连接 Mongodb 副本集 mongodb admin email protected cdn cgi l email protecti
  • MongoTemplate upsert - 从 pojo 进行更新的简单方法(哪个用户已编辑)?

    这是一个简单的 pojo public class Description private String code private String name private String norwegian private String en
  • 在android中创建SQLite数据库

    我想在我的应用程序中创建一个 SQLite 数据库 其中包含三个表 我将向表中添加数据并稍后使用它们 但我喜欢保留数据库 就好像第一次安装应用程序时它会检查数据库是否存在 如果存在则更新它 否则如果不存在则创建一个新数据库 此外 我正在制作
  • 表与多个表具有一对一的关系

    1 一个表可以和多个表建立一对一的关系吗 为了更清楚地说明 如果我想做插入 第一个表将受到影响并且 只有一张其他表会受到影响 2 如果是这样 主键将如何 3 另外 如果我想检索多条记录 查询会是什么样子 从这些表中 谢谢 一个表可以和多个表
  • postgresql 不同的不工作

    我使用以下代码从数据库获取值 但是当我编写这段代码时 测试看看问题出在哪里 我注意到查询没有从数据库中获取不同的值 这是查询 select distinct ca id as id acc name as accName pIsu name
  • 护照本地猫鼬帐户注册的附加字段?

    我将 Passport local mongoose 与 Node js Express js MongoDB 一起用于 Web 应用程序 我想使用用户名字段 密码字段 公司名称字段和电话号码字段 所有字段 来注册用户作为字符串 但是 我只
  • MySQL JOIN 滥用?情况会变得有多糟糕?

    我读了很多关于关系数据库的文章 在每个 SELECT 上使用许多 JOIN 语句 但是 我一直想知道滥用这种方法从长远来看是否会出现任何性能问题 例如 假设我们有一个users桌子 我通常会添加 最常用 的数据 而不是进行任何额外的联接 例
  • 使用 Flyway 和 Hibernate 的 hbm2ddl 在应用程序的生命周期中管理数据库模式

    我正在开发 Spring Hibernate MySql 应用程序 该应用程序尚未投入生产 我目前使用 Hibernatehbm2ddl该功能对于管理域上的更改非常方便 我也打算用Flyway用于数据库迁移 在未来的某个时候 该应用程序将首
  • 我可以将 MongoDB 与实体框架一起使用吗?

    实体框架有可能支持MongoDB数据库吗 有人写过实体框架MongoDB Provider吗 简短的回答 不 这肯定是可能的 但不合理 MongoDB 是文档数据库 不支持集合之间的任何物理关系 EF 非常适合 SQL MySQL 等关系数
  • 了解新的 mongo id 并将其与 Iron-router 一起使用

    我有一个简单的帖子路线来寻找帖子 id 问题是pathFor助手创建这样的路径 ObjectID 52e16453431fc2fba4b6d6a8 我猜 mongoDB 插入已更改 现在 id对象在其内部包含另一个对象 称为 str 这是我
  • Spring Data MongoDB:聚合框架 - 使用嵌套属性进行排序会抛出无效引用

    I found Spring论坛上的这篇文章 http forum spring io forum spring projects data nosql 130522 spring data mongodb aggregation fram
  • 如何对 SQL 进行多次查询

    我正在尝试创建一个表 并在 PHP 脚本的帮助下在数据库中插入一些值 虽然只插入 1 行 但效果很好 当我尝试输入更多行数时 出现错误 我需要为每个查询编写完整的插入语句 因为我正在使用在线 Excel 到 SQL 查询转换器
  • MySQL InnoDB 约束不起作用

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • pg_restore错误:角色XXX不存在

    尝试将数据库从一个系统复制到另一个系统 涉及的版本是9 5 0 源 和9 5 2 目标 源数据库名称是foodb与主人pgdba并且目标数据库名称将被命名foodb dev与主人pgdev 所有命令都在将托管副本的目标系统上运行 The p
  • 在 MongoDB 上,当我的回调位于“find”内部时,如何限制查询?

    我在 MongoDB 中有这个查询 db privateMessages find or fromId userId toId socket userId fromId socket userId toId userId function
  • Mongoose 和 Promise:如何获取查询结果数组?

    使用猫鼬从数据库和 Q 中查询结果以获取承诺 但发现很难只获取可用用户列表 目前我有一些这样的东西 var checkForPerson function person people mongoose model Person Person
  • 从 Azure 应用服务连接到 MongoDB Atlas 集群

    我在 Azure 上有一个 Web 应用程序 它连接到 Atlas cloud mongodb com 上托管的 MongoDB 集群 我想使用 Atlas 这样我就不必关心 MongoDb 配置 问题是我的集群连接超时 我必须在我的 mo

随机推荐