将数据作为对象与数组存储在MongoDb中以实现写入性能

时间:2016-03-04 20:22:11

标签: javascript mongodb

我应该将对象存储在数组中还是存储在对象中,并且写入速度最重要?

我试图决定数据是应该存储为对象数组,还是使用mongodb文档中的嵌套对象。

在这种特殊情况下,我会跟踪我添加和更新的一组不断更新的文件,文件名作为密钥和文件中处理的行数。

该文档看起来像这样

{
  t_id:1220,
  some-other-info: {}, // there's other info here not updated frequently
  files: {
    log1-txt: {filename:"log1.txt",numlines:233,filesize:19928},
    log2-txt: {filename:"log2.txt",numlines:2,filesize:843}
  }
}

或者

{
  t_id:1220,
  some-other-info: {},
  files:[
    {filename:"log1.txt",numlines:233,filesize:19928},
    {filename:"log2.txt",numlines:2,filesize:843}
  ]
}

我假设处理文档,特别是在更新时,处理对象更容易,因为对象的位置可以通过名称来确定;与数组不同,我必须查看每个对象的值,直到找到匹配为止。

由于对象键具有句点,因此我需要转换(或删除)句点以创建有效键(fi.le.logfilelogfi-le-log)。 我并不担心文件的问题。可能出现重复名称(例如fi.le.logfi-le.log)所以我更喜欢使用对象,因为文件数量相对较小,但更新频繁。

或者在单独的集合中处理这些数据以获得最佳写入性能会更好......

{
    "_id": ObjectId('56d9f1202d777d9806000003'),"t_id": "1220","filename": "log1.txt","filesize": 1843,"numlines": 554
},
{
    "_id": ObjectId('56d9f1392d777d9806000004'),"t_id": "1220","filename": "log2.txt","filesize": 5231,"numlines": 3027
}

1 个答案:

答案 0 :(得分:2)

据我所知,你在谈论写速度,没有任何阅读考虑。因此,我们必须考虑如何插入/更新您的文档。

我们必须进行比较(假设您知道要替换的_id,请在示例{key}log1-txt中)使用密钥名称替换log2-txt

db.Col.update({ _id: '' }, { $set: { 'files.{key}': object }})

vs

db.Col.update({ _id: '', 'files.filename': '{key}'}, { $set: { 'files.$': object }})

第二个意味着MongoDB必须浏览数组,找到匹配的索引并更新它。第一个意味着MongoDB只更新指定的字段。

最差: 如果数组中不存在匹配的filename,则第二个命令将不起作用!所以你必须执行它,检查nMatched是否为0,如果是,则创建它。那个真的写错速度很快(请参阅此处MongoDB: upsert sub-document)。

如果你永远不会/几乎从不在这个集合上使用读取查询/聚合框架:去第一个,这会更快。如果您想要聚合,展开,对您解析的文件进行一些分析以获得有关文件大小和行号的统计信息,您可以考虑使用第二个,您将避免一些头痛。

第一种解决方案的纯写入速度会更好。