3

背景

我将表行存储为 MongoDb 文档,每列都有一个名称。假设 table 有这些感兴趣的列: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
   }
}

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

{
   _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 }
   ]
}

问题

第二种方法是否有任何意义?

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

4

2 回答 2

1

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

像这样查询数据库要简单得多: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 会生成更好的查询计划,因为结构要简单得多(尚未测试)

第二个例子的优点:

  • 允许具有相同键/字段的多个条目,但我认为这对您的情况没有用
  • 数组上的单个索引可用于其所有条目,而不管它们的字段名称如何
于 2013-10-29T06:54:40.567 回答
1

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

于 2013-10-29T06:45:16.903 回答