Mongodb Агрегация, чтобы получить Резюме - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь найти уравнение агрегации, используя Spring Data Mongodb, и изо всех сил пытаюсь получить его правильно:

Допустим, у меня есть такие данные в mongodb:

{ "_id": 1, "channel": "fb", "store": "store1"},
{ "_id": 2, "channel": "app", "store": "store2"},
{ "_id": 3, "channel": "sms", "store": "store3"},
{ "_id": 4, "channel": "fb", "store": "store4"},
{ "_id": 5, "channel": "app", "store": "store3"},
{ "_id": 6, "channel": "app", "store": "store2"},
{ "_id": 7, "channel": "sms", "store": "store1"},
{ "_id": 8, "channel": "fb", "store": "store4"},
{ "_id": 9, "channel": "app", "store": "store2"},
{ "_id": 10, "channel": "fb", "store": "store2"},

Теперь я хочу предоставить сводку по каждому магазину с общим количеством каждого канала в объекте, который имеет:

class Summary {
  private String store;
  private int fbCount;
  private int smsCount;
  private int appCount;
  private int totalCount;
}

Если кто-нибудь может мне помочь с этим, я был бы очень признателен. Похоже, у него должно быть очень очевидное решение, но мои агрегирующие запросы не работают должным образом.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

@ andranikasl хорошо стартовал, но вам нужно преобразовать свои документы, чтобы они соответствовали ожидаемому результату (и вашему объекту). Вот способ:

db.collection.aggregate([
  {
    $group: {
      "_id": {
        "store": "$store",
        "channel": "$channel"
      },
      count: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      _id: "$_id.store",
      channels: {
        $push: {
          k: "$_id.channel",
          v: "$count"
        }
      }
    }
  },
  {
    $addFields: {
      channels: {
        $arrayToObject: {
          $concatArrays: [
            "$channels",
            [
              {
                k: "totalCount",
                v: {
                  $sum: "$channels.v"
                }
              }
            ]
          ]
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      store: "$_id",
      fbCount: {
        $ifNull: [
          "$channels.fb",
          0
        ]
      },
      smsCount: {
        $ifNull: [
          "$channels.sms",
          0
        ]
      },
      appCount: {
        $ifNull: [
          "$channels.app",
          0
        ]
      },
      totalCount: {
        $ifNull: [
          "$channels.totalCount",
          0
        ]
      }
    }
  }
])

Вы можете проверить это здесь

0 голосов
/ 05 ноября 2018

Вы можете сделать что-то вроде этого:

db.collectionName.aggregate([
    {
        $group: {
            "_id": {
                "store": "$store",
                "channel": "$channel"
            },
            count: {
                $sum: 1
            }
        }
    }
])

Этот запрос будет возвращать счетчик для каждого store и channel.

Или, если вы хотите получить счет в одном объекте, попробуйте:

db.collectionName.aggregate([
    {
        $group: {
            "_id": "$store",
            fb:  {$sum: {$cond: [{$eq: ['$channel', 'fb']}, 1,0]}},
            app: {$sum: {$cond: [{$eq: ['$channel', 'app']}, 1,0]}},
            sms: {$sum: {$cond: [{$eq: ['$channel', 'sms']}, 1,0]}},
            total: {
                $sum: 1
            }
        }
    }
])

Если я могу сделать что-нибудь еще, не стесняйтесь спрашивать:).

...