【问题标题】:Pull Multiple Distinct Fields into New Object from MongoDB从 MongoDB 将多个不同的字段拉入新对象
【发布时间】:2021-07-01 14:37:24
【问题描述】:

我觉得我的问题将有一个非常简单的答案,但它就是这样。

我有一个类似 MongoDB 的结构

{  
...  
a: [array elements],  
b: [array elements],  
c: [array elements],  
...  
}  

我正在使用 Mongoose,目前我有 3 个 find 不同的呼叫发出。

Model.find().distinct('a', ...)  
Model.find().distinct('b', ...)  
Model.find().distinct('c', ...)

这确实给了我想要的东西,但我想在一个电话中获得信息。我想我也许可以使用聚合来执行此操作并获得一个看起来像的新对象

{  
a: [distinct array elements],  
b: [distinct array elements],  
c: [distinct array elements]  
}

从 MongoDB 一次性获取此信息的最快方法是什么?

【问题讨论】:

    标签: node.js arrays mongodb mongoose


    【解决方案1】:

    可以使用聚合管道在一个查询中获取所有 3 个,例如:

    [ 
      {$facet:{
          a: [{$group:{_id:null, values:{$addToSet:"$a"}}}],
          b: [{$group:{_id:null, values:{$addToSet:"$b"}}}],
          c: [{$group:{_id:null, values:{$addToSet:"$c"}}}],
      }}
    ]
    

    但是,这需要从磁盘读取每个文档,将整个列表迭代 3 次,并在同一聚合阶段在内存中构建集合。在大型数据集中,这可能会超过单个阶段的内存限制。

    如果集合在{a:1} 上有索引,则查询Model.find().distinct('a') 可以使用“DISTINCT_SCAN”阶段,这意味着它只会查询索引来获取值,而不会直接读取任何文档。

    如果所有 3 个字段都已编入索引,则 3 个单独的 distinct 查询将是最快的方法。

    【讨论】:

    • 限制正在阅读的文档数量非常有意义。我对数据库真的很陌生,所以感谢您向我介绍索引。我也在尝试限制我的 API 和数据库调用(又名:网络流量),所以有没有办法让聚合管道也使用索引,或者我只是不了解聚合管道的工作原理。
    • 还有一个问题。如果我在 Mongoose 中为数组类型设置索引,它会索引数组中的值还是整个数组本身?我只想索引值。
    • 单独的问题应单独提出。如果这不能充分回答,请提交一个新问题:stackoverflow.com/questions/7396219/…
    猜你喜欢
    • 2016-05-15
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 2015-04-27
    • 2020-11-25
    • 1970-01-01
    • 2014-07-02
    相关资源
    最近更新 更多