#mongodb #mongodb-query #aggregation-framework #aggregate
Вопрос:
Я пытаюсь получить совокупную работу в mongo, вот простая структура json, и как я хотел бы получить совокупность.
// this is the format of the collection
[
{
_id: 6154f64df41fa3628ac2062a,
type: 'email',
platform: 'google',
apiDataId: '17c33ac4735c80bf',
timestamp: '2021-09-01',
userId: '6132a04892559282c40fd29a',
groupId: '6132a0cb74af9d82df74e918',
__v: 0
},
{
_id: 6154f64df41fa3628ac2062b,
type: 'call',
platform: 'yahoo',
apiDataId: '17c2d25e2ccf770d',
timestamp: '2021-09-01',
userId: '6132a04892559282c40fd29a',
groupId: '6132a0cb74af9d82df74e918',
__v: 0
},
{
_id: 6154f64df41fa3628ac2062c,
type: 'email',
platform: 'google',
apiDataId: '2021-09-03',
timestamp: '1632958029720',
userId: '6132a04892559282c40ff2a9',
groupId: '6132a0cb74af9d82df74e918',
__v: 0
},
{
_id: 6154f64df41fa3628ac2062d,
type: 'email',
platform: 'google',
apiDataId: '17c273deffc51cc9',
timestamp: '2021-09-04',
userId: '6132a04892559282c40fd29a',
groupId: '6132a0cb74af9d82df74e918',
__v: 0
},
{
_id: 6154f64df41fa3628ac2062e,
type: 'call',
platform: 'yahoo',
apiDataId: '17c14c85f6a89088',
timestamp: '2021-09-04',
userId: '6132a04892559282c40ff2a9',
groupId: '6132a0cb74af9d82df74e918',
__v: 0
}
]
Я начал писать совокупность, но мне трудно понять совокупность,
aggregate([
{ $match: { groupId: groupId } },
{ $group: { _id: "$userId" } },
{ $group: { timestamp: "$timestamp" } },
{ $project: { "groupId": 0, "userId": 0} },
{ $count: "num_data" }
]).exec()
то, чего я пытаюсь достичь, отредактировано
[
groupId: '6132a04892559282c40fd29a',
userId: {
calls: [
"2021-09-01": {platform: "yahoo"},
"2021-09-03": {platform: "yahoo"},
...
],
emails: [
"2021-09-01": {platform: "google"},
"2021-09-04": {platform: "google"},
...
],
},
userId: { ... }
]
конечно, эта агрегация не работает, мне трудно понять и попытаться понять, какие заказы и какие вещи использовать.
Комментарии:
1. Можете ли вы добавить пример документа со значениями?
2. Я добавил больше деталей! было бы здорово, если бы вы могли просмотреть еще раз.
Ответ №1:
Является ли эта совокупность тем, что вы ищете?
db.collection.aggregate([
{
$match: {
groupId: "1"
}
},
{
$group: {
_id: "$userId",
count: {
$sum: 1
},
apiDataId: {
"$first": "$ROOT"
}
}
},
{
"$project": {
"count": "$count",
"apiDataId": {
"timestamp": "$apiDataId.timestamp",
"platform": "$apiDataId.platform",
"type": "$apiDataId.type",
"data": "$apiDataId.data"
}
}
}
])
данные
[
{
"groupId": "1",
"timestamp": "1",
"userId": "1",
"platform": "1",
"apiDataId": "1",
"type": "1",
"data": "1"
},
{
"groupId": "1",
"timestamp": "1",
"userId": "2",
"platform": "3",
"apiDataId": "4",
"type": "5",
"data": "6"
},
{
"groupId": "1",
"timestamp": "3",
"userId": "2",
"platform": "7",
"apiDataId": "8",
"type": "9",
"data": "9"
},
{
"groupId": "2",
"timestamp": "1",
"userId": "1",
"platform": "1",
"apiDataId": "1",
"type": "1",
"data": "1"
}
]
Результат
[
{
"_id": "2",
"apiDataId": {
"data": "6",
"platform": "3",
"timestamp": "1",
"type": "5"
},
"count": 2
},
{
"_id": "1",
"apiDataId": {
"data": "1",
"platform": "1",
"timestamp": "1",
"type": "1"
},
"count": 1
}
]
Обновление: 2021-10-03
агрегировать по идентификатору пользователя, затем по дате
db.collection.aggregate([
{
$match: {
__v: 0
}
},
{
$group: {
_id: {
u: "$userId",
t: "$timestamp"
},
count: {
$sum: 1
},
"timestampList": {
"$push": "$ROOT"
}
}
},
{
$group: {
_id: "$_id.u",
count: {
$sum: 1
},
"userList": {
"$push": "$ROOT"
}
}
}
])
Комментарии:
1. это работает идеально, большое вам спасибо. Еще один вопрос, если вы не возражаете, можно ли создать другую группу на основе дат? формат метки времени просто «2021-10-02», я хочу сгруппировать по идентификатору пользователя и внутри каждой группы идентификаторов пользователей сгруппировать данные по метке времени? возможно ли это?
2. Да, это возможно, проверьте мое обновление.