mongodb - MongoDB聚合:对象键中的元素计数
问题描述
我有一个这样的 MongoDB 文档:
[
{
"_id": {
"$oid": "5ff09030cd55d6d9f378d460"
},
"username": "a value",
"userid": "123456",
"last_access_ts": 1612426253,
"last_access": "2021-2-4 9:10:53",
"anotherid": 12345678910,
"verified_date": "2021-1-2 16:24:32",
"verified_ts": 1609601072,
"group_users": {
"-1001159747589": [
{
"anotherid": 12345678910,
"userid": "123456"
}
],
"-1001143137644": [
{
"anotherid": 12345678910,
"userid": "123456"
}
],
"-1001368608972": [
{
"anotherid": 12345678910,
"userid": "123456"
}
]
},
"registered_access": "2021-1-2 16:24:42",
}
]
我有两个问题。
第一个:我需要计算每个group_users[key]
对象内的元素,我被这个聚合所困:
db.collection.aggregate([
{
$match: {
username: "a value"
}
},
{
$project: {
_id: 1,
userid: 1,
"groups": {
"$objectToArray": "$group_users"
}
}
},
{
$unwind: "$groups",
},
])
这个聚合给了我这个结果:
[
{
"_id": ObjectId("5ff09030cd55d6d9f378d460"),
"groups": {
"k": "-1001449720492",
"v": [
{
"anotherid": 12345678910,
"userid": "123456"
}
]
},
"userid": "123456"
},
{
"_id": ObjectId("5ff09030cd55d6d9f378d460"),
"groups": {
"k": "-1001159747589",
"v": [
{
"anotherid": 12345678910,
"userid": "123456"
}
]
},
"userid": "123456"
},
{
"_id": ObjectId("5ff09030cd55d6d9f378d460"),
"groups": {
"k": "-1001143137644",
"v": [
{
"anotherid": 12345678910,
"userid": "123456"
}
]
},
"userid": "123456"
}
]
我如何计算每个单曲groups[v]
然后重新分组数据?我希望得到如下结果:
{
... some user data
"groups": {
"group_key": "count",
"second_group_key": "count",
"third_group_key": "count"
}
}
是否可以聚合或我需要循环代码?
我的第二个问题总是关于group_users
. 是否可以递归地在group_users
对象内部拥有用户数据?
我的意思是,里面的每个对象group_users
都是一个用户数组;从这个数组中,我可以使用字段或字段获取用户数据(可能带有$graphLookup
?)?userid
anotherid
作为第二个聚合的结果,我想要这样的东西:
{
... some user data
"groups": {
"group_key": [{"userid": userid, "username": username}],
"second_group_key": [{"userid": userid, "username": username}],
"third_group_key": [{"userid": userid, "username": username}]
}
}
显然,我可以将这种“递归”限制为每次 10 个元素。
感谢您的任何建议。
解决方案
$objectToArray
将group_users
对象转换为数组$let
绑定变量group_arr
以在指定的表达式中使用,并返回表达式的结果。$map
迭代绑定变量的循环group_arr
,获取 v 的总元素的大小并返回 k 和 v,$arrayToObject
将返回的数组从转换$map
为对象
db.collection.aggregate([
{ $match: { username: "a value" } },
{
$project: {
_id: 1,
userid: 1,
groups: {
$let: {
vars: { group_arr: { $objectToArray: "$group_users" } },
in: {
$arrayToObject: {
$map: {
input: "$$group_arr",
in: {
k: "$$this.k",
v: { $size: "$$this.v" }
}
}
}
}
}
}
}
}
])
第二个问题,
$unwind
解构groups
数组$lookup
带有管道,匹配anotherid
$in
条件并返回必填字段$group
通过_id
并重建groups
数组$arrayToObject
将groups
数组转换为对象
db.collection.aggregate([
{ $match: { username: "a value" } },
{
$project: {
_id: 1,
userid: 1,
groups: { $objectToArray: "$group_users" }
}
},
{ $unwind: "$groups" },
{
$lookup: {
from: "collection",
let: { anotherid: "$groups.v.anotherid" },
pipeline: [
{ $match: { $expr: { $in: ["$anotherid", "$$anotherid"] } } },
{
$project: {
_id: 0,
userid: 1,
username: 1
}
}
],
as: "groups.v"
}
},
{
$group: {
_id: "$_id",
groups: { $push: "$groups" },
userid: { $first: "$userid" }
}
},
{ $addFields: { groups: { $arrayToObject: "$groups" } } }
])
推荐阅读
- tcp - 在 Postman Beta 功能的 WebSocket 请求中传递端口
- gcc - 英特尔 MPI 2019 始终使用 gcc 版本 4.9.3
- vsto - 如何在 Office vsto 插件开发中使用不同的配置文件进行开发和生产
- swift - 我搜索并搜索了 SwiftUI Switch Case Menu Cycle?
- amazon-web-services - Github Action ->“错误:禁止:无效凭证或此 AWS S3 存储桶名称可能已被使用”
- amazon-web-services - 编辑部署为容器映像的 AWS lambda 函数代码
- mysql - 根据表 2 上的条件在表 1 中插入 - MySQL
- sql - 在数据库中查找每个季度上个月的第一天?
- python-3.x - python pandas中数据框的屏蔽字符串和电话号码
- gitlab - Gitlab CI:为什么允许下一个阶段运行