如何使用 mongodb 中的聚合在嵌入文档的数组中执行操作?

Posted

技术标签:

【中文标题】如何使用 mongodb 中的聚合在嵌入文档的数组中执行操作?【英文标题】:How could use aggregates in mongo to do operations in an array embedded inside a document? 【发布时间】:2018-10-11 22:17:32 【问题描述】:

假设我有一组用户。每个用户都有资产。我想对资产执行一些统计测量。但为了能够做到这一点,我只需要将投影中的 assets 作为聚合的输入。这是如何实现的?

我希望能够对资产进行大量聚合操作。这些操作将包括过滤、限制和跳过,因此我将使用 $skip$match$limit 等运算符。但为了让我在嵌入数组上执行这些操作,我需要一个运算符,它接受一个 user 文档并输出嵌入其中的 assets 数组。

我只是想要一个运算符,它接受具有以下架构的用户文档并输出我进一步对其执行聚合操作的资产数组。

user:
   name: string,
   assets: Asset[],
   age: number

我尝试了这种聚合操作,但它没有按预期工作。

db.getCollection('users').aggregate( [ 
 $match: _id: ObjectId("5ae837dca9a8e04dd0689824")  ,
 $project :  assets: 1   ,
] )

它输出一个数组,其中包含一个用户文档,其中嵌入了资产,就像这样

[
"_id" : ObjectId("5ae837dca9a8e04dd0689824"),
"assets" : [_id:ObjectId("1"), assetName: 'tt' , _id : ObjectId("2"), assetName: 'rr']
] 

我需要像下面这样的输出

[
_id:ObjectId("1"), assetName: 'tt', 
_id:ObjectId("2"), assetName: 'rr'
]

【问题讨论】:

请出示您的示例文件和预期输出 完成。我添加了一个解释 这还不够解释。最好展示一些示例文档和您期望达到的结果。理想情况下,我们真的希望您也“展示您的尝试”,因为我们很乐意帮助您编写代码,但不太乐意像“免费”一样完成您的工作。请参阅How do I ask a good question?,它是各种链接主题,包括How to create a Minimal, Complete, and Verifiable example 我又更新了我的问题。 【参考方案1】:

两个步骤来做到这一点(加上$match):

$unwind 将一组子文档转换为具有一个子文档的多个文档 $replaceRoot 将子文档提升到新的根目录

试试:

db.users.aggregate([
     $match: _id: ObjectId("5ae837dca9a8e04dd0689824") ,
     $unwind: "$assets" ,
     $replaceRoot:  newRoot: "$assets"  
])

【讨论】:

感谢您的回答和赞许,但您不认为有更高效的解决方案。 @YoussefSherif 我什么都没有想到,因为我相信这两个运算符没有替代品。你说的高性能是什么意思?如果您从 $match 开始并在单个文档上执行 $unwind 那么您的结果集应该不会那么大,我猜

以上是关于如何使用 mongodb 中的聚合在嵌入文档的数组中执行操作?的主要内容,如果未能解决你的问题,请参考以下文章

聚合中的mongodb $count 太慢,超过1mill。数据库中的文档

如何匹配 MongoDB 中嵌入式数组或文档中的字符串?

使用 MongoDB 中的文档属性过滤器获取嵌入数组中的扁平文档数组

如何过滤mongodb聚合中的主数组

使用 Spring Data MongodB 更新嵌入式 mongodb 文档中的数组字段?

如何在 mongoDB 中存储地理空间信息