【问题标题】:How to modify array single subdocument without loading that entire array in-memory?如何修改数组单个子文档而不将整个数组加载到内存中?
【发布时间】:2018-11-26 14:32:03
【问题描述】:

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

我想更新一个嵌入的数组子文档而不改变它在数组索引中的位置。并且无需将整个数组加载到内存中,因为该数组将来可能会变得非常大。


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

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

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

有什么方法可以实现我想要的吗?理想情况下是通过 Mongoose 抽象,所以所有的 Mongoose 中间件,如验证、插件等。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    其实提交这个问题后就找到答案了。

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


    这里有一些代码示例,它使用_id 查询某个子文档,然后使用$set 更新该子文档属性$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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-17
      相关资源
      最近更新 更多