совокупная группа монго, совпадение, проект, количество

#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
  }
]
 

mongoplayground


Обновление: 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. Да, это возможно, проверьте мое обновление.