在什么时候通过prop查询nosql更好,而不是在文档中存储大数组&查询该文件ID?

时间:2016-05-16 19:44:08

标签: arrays mongodb

我将文档存储在json格式的nosql(mongo或其他)数据存储区中,如此

*编辑开始*

{
    _id : 9182798172981729871
    propertyBBBB: [
       {
           propertyCCCCC: "valueCCCC",
           propertyDDDDD: [ "valueDDDD", "valueEEEE", "valueFFFF" ]
       }, {
           propertyCCCCC: "valueGGGG",
           propertyDDDDD: [ "valueHHHH", "valueIIII", "valueFFFF" ]
       }
       ....
    ]
}


.find( { _id : "9182798172981729871" } , 
       { propertyBBBB : { propertyDDDD : {"$elemMatch":{"$in":['refineaquerystringvar']}}}} )

MongoDB nested array query

****编辑结束****

目前我正在通过_id进行查询,并在fetch返回文档后对嵌套数组执行逻辑。

但我正在寻找查询的更大灵活性所以我正在考虑制作一个新的nosql(mongo或其他)集合,其中包含看起来像propertyBBBB值的文档

*编辑开始*

   {
       _id: 9234792837498237498237498
       parentid: 9182798172981729871
       propertyCCCCC: "valueCCCC",
       propertyDDDDD: [ "valueDDDD", "valueEEEE", "valueFFFF" ]
   }

   {
       _id: 9234792837498237498237497
       parentid: 9182798172981729871
       propertyCCCCC: "valueCCCC",
       propertyDDDDD: [ "valueDDDD", "valueEEEE", "valueFFFF" ]
   }


.find( { parentid : "9182798172981729871" } , 
       { propertyDDDDD : {"$elemMatch":{"$in":['refineaquerystringvar']}}} )

MongoDB nested array query

****编辑结束****

但是我不想失去我的查询速度,因为在这种做事方式中我使用更多的逻辑来查询parentid作为补充参数而不是主要的获取。我也提取了很多物品,而不是确定我每次都拿一个。

所以我的问题是:

在什么时候最好通过属性查询mongo而不是在文档中存储大数组并查询该文档_id?数组(或返回查询)的长度有多大会使一个约定比另一个约定更有利?

2 个答案:

答案 0 :(得分:3)

答案实际上取决于您的数据的用例以及您希望在查询中检索的内容。需要注意的是;

  1. MongoDb不进行连接,因此任何需要将数据粘合在一起的东西都需要在应用程序中使用额外的逻辑,并且需要额外的CPU功率才能这样做 - 因此更小的记录可能无法加速应用程序,实际上大多数人都认为使用规范化数据模式比使用非规范化模式要慢得多。

  2. MongoDB不支持超过16Mb的记录 - 因此,如果您的阵列结构可以无限增长,则可能会出现问题 - 例如,拥有应用程序的所有用户数组将是一个糟糕的设计。 / p>

  3. 你已经在你的查询中使用了$elemMatch指令,这很好,因为它减少了通过网络传输的数据量到实际需要的数据量 - 但是非常大的记录大小仍然可能是一个问题。 disk io,但是在许多Mongo数据库中,活动数据集完全适合内存,因此假设大多数操作都是读取,IO就不那么重要了。如果写入次数(更新)是操作的大部分,那么值得考虑的是,只更新数组中的一个元素会导致整个对象被写入数据库,因此如果记录非常大则只需更改一个字节会导致重大IO - 在会话中收集用户事件就是这样一种用例,其中将事件添加到数组可能最终成为一个糟糕的设计。

    如果非规范化数组中的find将返回多条记录(因为您使用_id查询,它会在您的情况下获胜)客户端的应用程序逻辑在规范化模式中可能非常难以构建以拼接记录和你可能想要避免的东西。

    它在规范化模型中可以想到的唯一好处是,如果你有大量的mongo分片,并且你希望find返回大量的记录,因为你可以并行化数据的检索来自多个主机,但每个查找返回的数据量必须非常大,以便您注意到差异。

    因此,总而言之,我认为出于性能原因,您希望将数据规范化的情况对于大多数人来说是最不可能的,也可能是微不足道的。如果你对数据有很好的理解,你可能想要运行一个基准测试,除非你得到一个实质性的(x2或x3)差异,我仍然会使用非规范化模型,因为你有简单易用的代码写。

    正如您所要求的那样,"官方消息来源"我可以参考mongodb-blogseries关于如何设计数据模型的文章,并且他们迭代我上面提到的相同点以及一些额外的提示。

答案 1 :(得分:0)

是的,您可以将数据加载到数组中 集合由文档组成。每个文档都可以映射为一个对象 最后你会把mongo集合加载为一个对象数组 我认为在服务器中处理大量对象没有问题,因为通常node.js和mongoDB通常托管在同一台服务器上。因此,在节点中处理大型数组时完成的工作可以平衡将在mongo中处理的工作