Как составить aggregate запрос в MongoDB для подсчета статистики?

Мне нужно составить правильно запрос чтобы получить:

  1. Сколько всего уникальных пользователей зашло

  2. Сколько всего уникальных пользователей зашло по странам

  3. Сколько всего уникальных пользователей зашло за сегодня

В моей коллекции есть такой тип данных:

{
  "_id": {
    "$oid": "65e8fa34d11452b28eaf7cff"
  },
  "domain": "site.com",
  "userAgent": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/116.0.1938.76 Safari/537.36",
  "ip": "157.55.39.204",
  "country": "US",
  "pub_id": "analytics",
  "date": {
    "$date": "2024-03-06T06:03:12.900Z"
  },
  "__v": 0
},
{
  "_id": {
    "$oid": "65e8fa37d11452b28eaf7d01"
  },
  "domain": "site2.com",
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
  "ip": "153.246.189.82",
  "country": "JP",
  "pub_id": "analytics",
  "date": {
    "$date": "2024-03-06T06:03:12.900Z"
  },
  "__v": 0
},
{
  "_id": {
    "$oid": "65e8fa39d11452b28eaf7d03"
  },
  "domain": "site3.com",
  "userAgent": "Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)",
  "ip": "54.36.148.164",
  "country": "FR",
  "pub_id": "analytics",
  "date": {
    "$date": "2024-03-06T06:03:12.900Z"
  },
  "__v": 0
}

Примечание:

Ip-адреса могут повторяться, так как один и тот же пользователь может зайти в разное время в один и тот же день.

Как мне правильно составить запрос с помощью aggregate в MongoDB?


Ответы (1 шт):

Автор решения: Alexander Petrov
db.collection.aggregate([
  {
    $group: { _id: "$ip" }
  },
  {
    $count: "unique users"
  }
])
db.collection.aggregate([
  {
    $group: {
      _id: "$country",
      count: { "$sum": 1 }
    }
  },
  {
    $group: {
      _id: "$_id",
      data: {
        $push: {
          k: "$_id",
          v: "$count"
        }
      }
    }
  },
  {
    "$addFields": {
      data: { "$arrayToObject": "$data" }
    }
  },
  {
    "$replaceRoot": { "newRoot": "$data" }
  }
])
db.collection.aggregate([
  {
    $match: {
      $expr: {
        "$eq": [
          {
            $dateTrunc: {
              date: "$date",
              unit: "day"
            }
          },
          {
            $dateTrunc: {
              date: "$$NOW",
              unit: "day"
            }
          }
        ]
      }
    }
  },
  {
    $group: { _id: "$ip" }
  },
  {
    $count: "unique today"
  }
])
→ Ссылка