在 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 文档,每列都有一个名称。假设表有这些感兴趣的列:Identifier
、Person
、Date
、Count
。 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 字段元素的数组?的主要内容,如果未能解决你的问题,请参考以下文章