node.js - 使用聚合框架转换具有两个嵌套文档的文档
问题描述
我需要使用聚合框架转换此文档
{
title: 'Sample title',
options: [
{ text: "yes", id: 0 },
{ text: "no", id: 1 }
],
votes: [
{ option_id: 1, user_id: 1 },
{ option_id: 1, user_id: 2 },
{ option_id: 1, user_id: 3 }
]
}
进入这个对象
{
title: 'Sample title',
result: [{ _id: 1, text: 'no', votes: 3}, { _id: 0, text: 'yes', votes: 0 }]
}
我试过的:
[
{ $match: { _id: poll_id } },
{ $unwind: '$votes' },
{
$replaceRoot: {
newRoot: { $mergeObjects: ['$votes', '$$ROOT'] }
}
},
{
$group: {
_id: '$option_id',
title: { $first: '$title' },
votes: { $sum: 1 }
}
}
]
这产生了这个结果:
[{ _id: 1, title: 'Sample Title', votes: 3}]
如果该选项没有投票,则将其排除在最终结果之外。我也不知道如何包含选项的文本。我已经阅读了 mongodb 参考,但我找不到任何东西。
解决方案
db.collection.aggregate([
{
"$addFields": {
"result": {
"$map": {
"input": "$options",
"as": "option",
"in": {
"_id": "$$option.id",
"text": "$$option.text",
"votes": {
"$size": {
"$filter": {
"input": "$votes",
"as": "vote",
"cond": {
"$eq": [
"$$vote.option_id",
"$$option.id"
]
}
}
}
}
}
}
}
}
},
{
"$project": {
title: "$title",
"result": {
$filter: {
input: "$result",
as: "option",
cond: {
$gt: ["$$option.votes", 0]
}
}
}
}
}
])
推荐阅读
- node.js - 将 jBPM 与 Node.js 和 PostgreSQL 集成
- c - 以递归方式打印具有其他列表(相同结构)元素的列表
- powershell - PowerShell 远程启动进程不起作用
- c# - 列表的扩展方法
无法识别 C# 类的实例方法 - javascript - 从已删除的 DOM 元素中分离 jQuery 侦听器
- css - 为什么在 2d 比例变换期间文本变得模糊和摆动
- ios - CollectionView 滚动更改选定的单元格
- spring-cloud-dataflow - 使用 Spring Cloud 数据流注册自定义 Spring Cloud 任务
- javascript - 如何根据输入的值更改输入的背景颜色
- reactjs - ReactJS - 在状态中存储 API 数据