首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mongodb:如何建模一个饼(从整体到一个小的部件集合)

mongodb:如何建模一个饼(从整体到一个小的部件集合)
EN

Stack Overflow用户
提问于 2013-02-06 18:07:01
回答 3查看 122关注 0票数 0

问题

我需要将一个定义为“整体”的文档建模到一个小的固定集合“部件”,在这个集合中,整体及其部分都是可查询的。

切片派是我需要的模型的一个很好的例子。进一步说明该领域:

  • 派:片有一个1:多(1-10)关系。每个饼片只属于一个饼,每个饼片有1-10片.
  • 在这个例子中,假设饼在创建时是切片的,并且切片的数量不会改变。
  • 馅饼总是用它的切片来查询。相反的情况并不一定是正确的,但是一个被查询的切片将需要访问有关饼饼的元数据。
  • 例如,假设“权重”是片的唯一属性。所有片共享的元数据比每个片的元数据要大得多。所有的切片都有相同的面包师,填充,外壳,厨房等。不需要将所有数据复制到每个切片都是理想的。
  • 切片和馅饼都必须通过整个饼的属性或片的属性有效地查询和排序。例子:
    • 把所有派都找出来,切成两片
    • 找到所有一片重大于10盎司的馅饼
    • 找到所有“樱桃”类型的切片
    • 找出所有馅饼中最重的五片

问题是:

考虑到以上各点,如何对pie及其slices进行有效的查询(如果可能的话,有效地存储)?

如果这很明显,请回答。阅读我迄今尝试过的两种方法,以及为什么这两种方法都不令人满意。

我试过的是:

1.嵌入

将部分嵌入到整个似乎是自然的选择中。

代码语言:javascript
复制
Pie {
  type: String, // `type` and other shared attrs are defined on Pie
  slices: [{
    _id: ObjectId
    weight: Number
  }]
}

有了这个,我可以按类型、重量、切片重量查询馅饼,也可以通过aggregateunzipproject查询各个樱桃饼片。

问题在于如何在单个片上对进行排序和查询。例如,如果我需要从所有馅饼中检索5个最重的切片(如上面的问题所述),该怎么办?我--这是可能的--聚合,我不知道怎么做。

2.单独的集合

在放弃了第一个模式之后,我又回到了使用两个单独的集合,并加入了一个引用id:

代码语言:javascript
复制
Pie {
  type: String // `type` and other shared attrs are defined on Pie ...
}

Slice {
  pie_id: ObjectId,
  type: String, // ... and duplicated to all slices
  weight: Number
}

这解决了我的查询问题,但介绍了更多。这里只复制了type。在我的实际应用程序中,这要糟糕得多,以至于我对Slice的模拟可能是90%的重复数据。

另一个问题是,每当我想要查询馅饼时,我必须再次查询所有的切片。此外,制作饼不再是原子操作,而是一批单独的插入。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-16 01:14:13

我的答案,虽然也许不是唯一或最好的答案,是去或不正确的数据在双方的关系。

本质上,slices嵌入在pie文档中,--切片存在于它们自己的集合中,完整地包含了重复的pie元数据。通过这种方式,可以独立地查询饼及其切片,而无需进行任何辅助查询。

双向复制存储有效吗?也许不会,但同样,存储在这里也不是问题。

这是否使更新文档变得更加复杂和多个操作?是的,但是更新将远比读取少得多,在这种情况下,读要重要得多。

票数 0
EN

Stack Overflow用户

发布于 2013-02-06 22:28:45

您看过这个吗?特别是http://docs.mongodb.org/manual/tutorial/model-tree-structures/,“带有子引用的模型树结构”似乎正是您所要寻找的。您只能在切片文档中存储最特定于特定切片的数据(例如片权重),以及在Pie文档中存储其他所有数据。

票数 0
EN

Stack Overflow用户

发布于 2013-02-06 22:54:50

你能用这样的结构吗?

代码语言:javascript
复制
{
    "_id" : ObjectId("5112d747819e326e6c37e1e3"),
    "pie" : {
        "type" : "cherry",
        "weight" : 500,
        "slices" : [
            {
                "slice_id" : ObjectId("5112d747819e326e6c37e1e1"),
                "type" : "square",
                "weight" : 75
            },
            {
                "slice_id" : ObjectId("5112d747819e326e6c37e1e2"),
                "type" : "triangle",
                "weight" : 75
            }
        ]
    }
}

然后您可以使用$unwind和$sort,例如:

代码语言:javascript
复制
db.q14735834.aggregate({$unwind: "$pie.slices"}, {$sort: {"pie.slices.weight":-1}}, {$limit:10})

以及进一步组合$group和其他聚合框架操作符来操作数据。

除了Alptigin引用的教程之外,聚合框架文档还可以使用:http://docs.mongodb.org/manual/applications/aggregation/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14735834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档