Несколько условий на одном столбце mongodb - PullRequest
0 голосов
/ 25 сентября 2019
{
    "_id" : ObjectId("5ccfe06e2434de5c345d058e"),
        "user_id" : 1,
    "event" : "eventA",
    "channel_id" : "1098",
    "channel_node_id" : "2177",
    "channel_name" : "New work",
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000"),
    "user_raw_data" : {
        "Name" : "akhilesh",
        "Mobile" : "1234567890",
        "Email" : "akhilesh@test.com"
},

{
    "_id" : ObjectId("5ccfe06e2434de5c345d058e"),
        "user_id" : 1
    "event" : "eventB,
    "channel_id" : "1098",
    "channel_node_id" : "2177",
    "channel_name" : "New work",
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000"),
    "user_raw_data" : {
        "Name" : "akhilesh",
        "Mobile" : "1234567890",
        "Email" : "akhilesh@test.com"
},
{
    "_id" : ObjectId("5ccfe06e2434de5c345d058e"),
        "user_id" : 1
    "event" : "eventC,
    "channel_id" : "1098",
    "channel_node_id" : "2178",
    "channel_name" : "New work",
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000"),
    "user_raw_data" : {
        "Name" : "akhilesh",
        "Mobile" : "1234567890",
        "Email" : "akhilesh@test.com"
}
,
{
    "_id" : ObjectId("5ccfe06e2434de5c345d058e"),
        "user_id" : 2
    "event" : "eventA,
    "channel_id" : "1098",
    "channel_node_id" : "2178",
    "channel_name" : "New work",
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000"),
    "user_raw_data" : {
        "Name" : "akhilesh",
        "Mobile" : "1234567890",
        "Email" : "akhilesh@test.com"
}

Теперь я хочу получить количество событий, выполненных пользователем до сих пор.Для eventA счетчик будет равен 2, для eventB 1 и для eventC равен 1. Но этот запрос будет иметь несколько условий, поэтому мое условие - получение счетчика только в случае выполнения пользователем (eventA или eventB) и eventC.Таким образом, в этом случае событие doc user id 2 не будет рассматриваться, поскольку они не были выполнены (eventA или eventB)

Также, наряду с совпадением событий с mutiple и / или условием, я также хочу применить фильтр к user_raw_data, чтобымой запрос должен быть таким

 db.web_channel_events.aggregate([
  {
    $match: {
      "channel_id": "1098",
      "channel_node_id": "2177"
    }
  },
  {
    $group: {
      "_id": {
        "user_id": "$user_id",
        "event": "$event"
      },
      "count": {
        $sum: 1
      }
    }
  },
  {
    $group: {
      "_id": "$_id.user_id",
      "event_details": {
        $push: {
          "k": "$_id.event",
          "v": "$count"
        }
      }
    }
  },
  {
    $match: {
      $and: [
        {
          $or: [
            {
              "event_details.k": "eventA",
              "event_details.v": {
                "$gte": 1
              }
            },
            {
              "event_details.k": "eventB",
              "event_details.v": {
                "$gte": 1
              }
            }
          ]
        },
        {
          "event_details.k": "eventC",
          "event_details.v": {
            "$gte": 1
          }
        },
        {
          "user_raw_data.Name": "akhilesh"
        }
      ]
    }
  },
  {
    "$unwind": "$event_details"
  },
  {
    $group: {
      "_id": "$event_details.k",
      "count": {
        $sum: "$event_details.v"
      }
    }
  }
]).pretty();

1 Ответ

0 голосов
/ 25 сентября 2019

Следующий запрос может дать нам ожидаемый результат:

db.collection.aggregate([
    {
        $group:{
            "_id":{
                "user_id":"$user_id",
                "event":"$event"
            },
            "user_id":{
                $first:"$user_id"
            },
            "event":{
                $first:"$event"
            },
            "count":{
                $sum:1
            }
        }
    },
    {
        $group:{
            "_id":"$user_id",
            "user_id":{
                $first:"$user_id"
            },
            "event_details":{
                $push:{
                    "k":"$event",
                    "v":"$count"
                }
            }
        }
    },
    {
        $addFields:{
            "event_details":{
                $arrayToObject:"$event_details"
            }
        }
    },
    {
        $match:{
            $and:[
                {
                    $or:[
                        {
                            "event_details.eventA":{
                                $gt:0
                            }
                        },
                        {
                            "event_details.eventB":{
                                $gt:0
                            }
                        }
                    ]
                },
                {
                    "event_details.eventC":{
                        $gt:0
                    }
                }
            ]
        }
    },
    {
        $group:{
            "_id":null,
            "eventA":{
                $sum:"$event_details.eventA"
            },
            "eventB":{
                $sum:"$event_details.eventB"
            },
            "eventC":{
                $sum:"$event_details.eventC"
            }
        }
    },
    {
        $project:{
            "_id":0,
            "event_details.eventA":"$eventA",
            "event_details.eventB":"$eventB",
            "event_details.eventC":"$eventC"   
        }
    }
]).pretty()

Набор данных:

{
    "_id" : ObjectId("5ccfe06e2434de5c345d0588"),
    "event" : "eventA",
    "user_id" : 1,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}
{
    "_id" : ObjectId("5d8b132388edcf85b0aaa609"),
    "event" : "eventA",
    "user_id" : 1,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}
{
    "_id" : ObjectId("5d8b132388edcf85b0aaa60a"),
    "event" : "eventB",
    "user_id" : 1,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}
{
    "_id" : ObjectId("5d8b132388edcf85b0aaa60b"),
    "event" : "eventC",
    "user_id" : 1,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}
{
    "_id" : ObjectId("5d8b132388edcf85b0aaa60c"),
    "event" : "eventC",
    "user_id" : 1,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}
{
    "_id" : ObjectId("5d8b132388edcf85b0aaa60d"),
    "event" : "eventC",
    "user_id" : 2,
    "created_at" : NumberLong("1557127278000"),
    "updated_at" : NumberLong("1557127278000")
}

Выход:

{ "event_details" : { "eventA" : 2, "eventB" : 1, "eventC" : 2 } }

Анализ запроса:

  • Группировка данных на основе user_id и event и вычисление количества этого конкретного инцидента
  • Группировка только на основе user_id и отправка события и его счетчика в массив event_details в виде пар ключ-значение
  • Преобразование event_details в объект
  • Применениеусловие, что количество событий для (A или B) и C должно быть больше, чем 0
  • Суммировать количество отдельных событий
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...