mongodb - 编写需要使用分组的 MongoDB 聚合查询时遇到问题
问题描述
我有一个集合,它存储用户活动数据,这些数据与用户是否对选定的关键字列表投赞成票或反对票有关,因为它们与标题目录相关。我需要在 Mongo 中执行一个聚合查询,它为我提供与所有用户的标题相关的每个关键字的累积分数 - 赞成票由 vote: true 和 downvote by vote: false 表示
使用 unwind 运算符作为我的第一步,然后是 group by,但这是我迷失的地方,因为我不确定是否按 titleId、keyword 和 vote 的组合进行分组;只是titleId 和关键字或只是titleId。以下是集合中数据的示例 -
期望在聚合查询的末尾看到一个按 titleId 分组的文档,其中包含一组对象,其中每个对象包含一个关键字和该关键字在该标题的上下文中的累积投票总数。
{
"_id" : ObjectId("5d2eb0b20e91d1941540e2b5"),
"titleId" : "111222",
"userId" : "993f1e69-c6b0-44eb-a8a6-5db5dc42d425",
"activity" : [
{
"keyword" : "Road Trip",
"vote" : true
},
{
"keyword" : "Friendship",
"vote" : true
},
{
"keyword" : "Family Movie",
"vote" : true
}
]
}
// ----------------------------------------------
{
"_id" : ObjectId("5d38fd270e91d1941559bee0"),
"titleId" : "111222",
"userId" : "f92c7118-8930-4d30-8e07-8363737a6866",
"activity" : [
{
"keyword" : "Road Trip",
"vote" : false
},
{
"keyword" : "Adventure",
"vote" : true
},
{
"keyword" : "Family Movie",
"vote" : true
}
]
}
// ----------------------------------------------
{
"_id" : ObjectId("5d38fd270e91d1941559bee0"),
"titleId" : "111222",
"userId" : "f92c7118-8930-4d30-8e07-8363737a6866",
"activity" : [
{
"keyword" : "Road Trip",
"vote" : false
},
{
"keyword" : "Adventure",
"vote" : false
},
{
"keyword" : "Family Movie",
"vote" : false
}
]
}
// ----------------------------------------------
{
"_id" : ObjectId("5d2eb0b20e91d1941540e2b5"),
"titleId" : "444222",
"userId" : "993f1e69-c6b0-44eb-a8a6-5db5dc42d425",
"activity" : [
{
"keyword" : "Educational film and videos",
"vote" : true
},
{
"keyword" : "Space",
"vote" : true
}
]
}
// ----------------------------------------------
{
"_id" : ObjectId("5d38fd270e91d1941559bee0"),
"titleId" : "444222",
"userId" : "f92c7118-8930-4d80-8e07-8363737a6866",
"activity" : [
{
"keyword" : "Action",
"vote" : false
},
{
"keyword" : "Adventure",
"vote" : false
},
{
"keyword" : "Sci Fi",
"vote" : true
}
]
}
期望看到一个按 titleId 分组的文档和一组对象,其中每个对象包含一个关键字以及该关键字在该标题的上下文中的累积投票总数。
解决方案
以下查询可以为我们提供预期的输出:
db.collection.aggregate([
{
$unwind:"$activity"
},
{
$group:{
"_id":{
"titleId":"$titleId",
"keyword":"$activity.keyword"
},
"votes":{
$sum:{
$cond:[
{
$eq:["$activity.vote",true]
},
1,
-1
]
}
}
}
},
{
$group:{
"_id":"$_id.titleId",
"titleId":{
$first:"$_id.titleId"
},
"activity":{
$push:{
"keyword":"$_id.keyword",
"votes":"$votes"
}
}
}
},
{
$project:{
"_id":0
}
}
]).pretty()
输出:
{
"titleId" : "111222",
"activity" : [
{
"keyword" : "Road Trip",
"votes" : -1
},
{
"keyword" : "Adventure",
"votes" : 0
},
{
"keyword" : "Friendship",
"votes" : 1
},
{
"keyword" : "Family Movie",
"votes" : 1
}
]
}
{
"titleId" : "444222",
"activity" : [
{
"keyword" : "Adventure",
"votes" : -1
},
{
"keyword" : "Sci Fi",
"votes" : 1
},
{
"keyword" : "Action",
"votes" : -1
},
{
"keyword" : "Educational film and videos",
"votes" : 1
},
{
"keyword" : "Space",
"votes" : 1
}
]
}
聚合阶段:
- 第一阶段:展开“活动”数组。现在数组的每个元素都有一个文档
- 第二阶段:根据标题ID和活动关键字进行分组并计算票数。1 表示赞成,-1 表示反对。
- 第三阶段:仅根据标题 ID 进行分组,并将所有活动合并到一个数组中
- 第四阶段:从输出中消除不必要的字段
推荐阅读
- r - 在表格中更改栏的颜色和方向
- java - List的Java反射数组
- javascript - 如何使用 Firefox 禁用对特定 javascript 函数的访问?
- python - Pandas / Databricks - 如果另一个日期时间列在分钟内有 x,则创建一个新的日期时间列
- r - 更改主题后,ggpairs 中的自定义图例消失
- c++ - 如何在 CObservation2DRangeScan 中设置扫描角度?
- matlab - 是否可以在 uiaxes 上绘制轮廓图?
- php - Base64_decode 到 PDF
- r - 为什么将列表与 %in% 进行比较会导致两个不同的输出?
- javascript - OpenLayers 和 React - 单击时使用,函数内部使用的值不会更新