在 MongoDB 中,何时使用简单的子文档,何时使用具有 2 字段元素的数组?

Posted

技术标签:

【中文标题】在 MongoDB 中,何时使用简单的子文档,何时使用具有 2 字段元素的数组?【英文标题】:In MongoDB, when to use a simple subdocument, when an array with 2-field elements? 【发布时间】:2013-11-04 23:01:24 【问题描述】:

背景

我将表行存储为 MongoDb 文档,每列都有一个名称。假设表有这些感兴趣的列:IdentifierPersonDateCount。 MongoDb 文档还有一些与表数据分开的额外字段,由timestamp 表示。列不是固定的(这就是为什么我首先使用无模式数据库来存储它们)。

将需要执行各种复杂但迄今为止未指定的查询。我不是很关心性能,尽管查询性能可能会成为瓶颈。一旦插入,文档将不会被修改(将创建一个具有相同Identifier 的新文档),并且插入不是很频繁(比如说,每天 1000 个新的 MongoDb 文档)。因此,随着时间的推移,数据量会稳步增长。

示例

直接的方法是收集 MongoDb 文档,例如:


   _id: XXXX,
   insertDate: ISODate("2012-10-15T21:26:17Z"),
   flag: true,
   data: 
       Identifier: "AB002",
       Person: "John002",
       Date: ISODate("2013-11-16T21:26:17Z"),
       Count: 1
   

现在我看到了另一种方法(例如在this question 接受的答案中),使用每个对象有两个字段的数组:


   _id: XXXX,
   insertDate: ISODate("2012-10-15T21:26:17Z"),
   flag: true,
   data: [
        field: "Identifier", value: "AB002" ,
        field: "Person", value: "John001" ,
        field: "Date", value: ISODate("2013-11-16T21:26:17Z") ,
        field: "Count", value: 1 
   ]

问题

第二种方法是否有意义?

如果是,那么如何选择使用哪个?特别是,是否有一些特定类型的查询使用一种方法很容易/便宜,而另一种方法很难/昂贵?有什么“经验法则”,或者两者的赞成名单?一种方法不方便的真实案例将特别有价值。

【问题讨论】:

【参考方案1】:

我不认为另一个例子here 和你的情况是一样的。在另一个示例中,他们正在创建具有两个答案之一的项目列表,这在数组中更合适,目标是返回与条件匹配的子文档列表。在您的示例中,您实际上只是在描述一个对象,因为它们都包含不同类型的信息,并且您不需要检索子文档的可搜索位。

【讨论】:

【参考方案2】:

在您的具体示例中,第一个版本更加合适和简单。您必须考虑如何查询您的文档。

这样查询数据库要简单得多:db.collection.find("data.Identifier": "AB002")

虽然我不能 100% 确定您为什么需要内部文档。为什么不能像这样构建您的文档:


   _id:  "AB002",
   insertDate: ISODate("2012-10-15T21:26:17Z"),
   flag: true,
   Person: "John002",
   Date: ISODate("2013-11-16T21:26:17Z"),
   Count: 1

第一个例子的优点:

查询简单 强制使用唯一键,但您的数据不会有两列同名 我认为 mongoDB 会生成更好的查询计划,因为结构要简单得多(尚未测试)

第二个例子的优点:

允许具有相同键/字段的多个条目,但我认为这对您的情况没有用 数组上的单个索引可用于其所有条目,无论其字段名称如何

【讨论】:

将它们放入子文档的原因是,子文档中的确切字段不固定,我仍然希望能够使用aggregate 获取它们(不确定是否有解决方法这)。另一个原因是为了防止将来发生名称冲突(例如,如果某些子文档有 flag 字段)。 @hyde,这是有道理的。出于兴趣,insertDate 是插入 mongoDB 还是插入原始表的时间? insertDate 从概念上讲是检测到原始数据更改的时间,但(至少目前)有效地将文档插入 MongoDB 集合的时间。我认为可以从 _id 中提取相同的信息,但是对于未知的未来需求,显式字段似乎更清晰、更灵活。 哦,好吧,我只是想提一下,时间是嵌入在_id中的,但你已经知道了。

以上是关于在 MongoDB 中,何时使用简单的子文档,何时使用具有 2 字段元素的数组?的主要内容,如果未能解决你的问题,请参考以下文章

何时在 Nodejs 中关闭 MongoDB 数据库连接

何时对 mongodb 中的多个键进行索引

MongoDB:存储和何时使用关系

鉴于新的索引交集功能,复合索引何时在 MongoDB 2.6 中仍然相关?

何时使用 MongoDB [关闭]

关于 python 何时自动创建数组副本的文档