如何在不将整个数组加载到内存中的情况下修改单个数组的子文档?

时间:2018-11-26 14:32:03

标签: node.js mongodb mongoose

我正在使用Node.js v8.12.0,MongoDB v4.0.4和Mongoose v5.3.1

我想更新嵌入式数组子文档而不更改其在数组索引中的位置。并且不将整个阵列加载到内存中,因为该阵列将来可能会变得很大。


我花了很多时间寻找如何实现这一目标,但是没有运气。

我尝试使用Mongo的$elemMatch来仅用单个相关的数组子文档加载该文档,但这不会以任何实际的方式保存该子文档。

我也研究了Mongoose数组set方法,但是为此,您需要具有子文档数组索引,因此这意味着我需要将整个数组加载到内存中,然后找到子文档索引。

有什么方法可以实现我想要的吗?理想情况下,是通过Mongoose抽象进行的,因此所有Mongoose中间件(如验证,插件等)都可以加入。

1 个答案:

答案 0 :(得分:0)

提交此问题后,实际上找到了答案。

对于将来查找它的任何人,可以将特殊的$运算符与$set结合使用。 (不过,我不确定这是否利用了猫鼬中间件。我需要对此进行一些测试。)


下面是一些代码示例,该示例使用_id查询某些子文档,然后使用someProperty更新该子文档属性$set,该属性使用与查询的子文档数组匹配的特殊运算符$位置/索引。

var doc = await SomeModel.findOneAndUpdate(
  {'someArray._id': 'xxx'},
  {'$set': {'someArray.$.someProperty': 'someValue'}},
); 

尽管如此,它仍然不是我要找的100%。因为返回的doc仍然具有完整的子文档数组(我假设仍在加载到内存中?),并且看来我不能将$elemMatch$set结合使用。


就我而言,在以后的工作中,我可能会重新设计数据库架构,以便这些嵌入的子文档将成为它们自己的文档,只是ObjectID引用“父”文档。


一些资源:

https://docs.mongodb.com/manual/reference/operator/update/positional/

https://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate