在MongoDb中将数据存储为对象与数组以提高写入性能

storing data as object vs array in MongoDb for write performance

本文关键字:数组 性能 高写入 对象 MongoDb 数据 存储      更新时间:2023-09-26

我应该将对象存储在数组中还是存储在给定写入速度的最重要的对象中?


我正在尝试决定是应该将数据存储为对象数组,还是在 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
}

我了解,您谈论的是写入速度,没有任何读取考虑。因此,我们必须考虑如何插入/更新文档。

我们必须进行比较(假设您知道要替换_id,请在示例中log1-txtlog2-txt中将{key}替换为键名):

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

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

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

最差的:如果数组中不存在匹配的filename,则第二个命令将不起作用!所以你必须执行它,检查nMatched是否为 0,如果是,则创建它。这真的是很糟糕的写入速度(参见此处MongoDB:upsert子文档)。

如果您永远不会/几乎从不在此集合上使用读取查询/聚合框架:请选择第一个,那会更快。如果你想聚合,展开,对你解析的文件做一些分析,以获得关于文件大小和行号的统计数据,你可以考虑使用第二个,你会避免一些头痛。

使用第一个解决方案,纯写入速度会更好。