Mongodb использует вложенный документ $ elemMatch для других полей в группе - PullRequest
0 голосов
/ 19 октября 2018

Мне нужно посчитать количество подписных действий в день.и вот моя коллекция user_events:

[
    {
        "user_id": 5,
        "events": [
            {
                "date": ISODate("2018-10-17T15:51:06.000Z"),
                "action": "subscribe" 
            },
            {
                "date": ISODate("2018-10-18T15:51:06.000Z"),
                "action": "unsubscribe" 
            },
            {
                "date": ISODate("2018-10-16T15:51:06.000Z"),
                "action": "charge" 
            },
            {
                "date": ISODate("2018-10-19T15:51:06.000Z"),
                "action": "subscribe" 
            }
        ]
    },
    {
        "user_id": 6,
        "events": [
            {
                "date": ISODate("2018-10-6T15:51:06.000Z"),
                "action": "subscribe" 
            },
            {
                "date": ISODate("2018-10-17T15:51:06.000Z"),
                "action": "unsubscribe" 
            },
            {
                "date": ISODate("2018-10-10T15:51:06.000Z"),
                "action": "charge" 
            },
            {
                "date": ISODate("2018-10-26T15:51:06.000Z"),
                "action": "send-code" 
            },
            {
                "date": ISODate("2018-10-11T15:51:06.000Z"),
                "action": "charge" 
            },
            {
                "date": ISODate("2018-10-18T15:51:06.000Z"),
                "action": "subscribe" 
            }
        ]
    },
]

Мне нужно агрегировать данные на основе даты подписки.так что просто вложенные документы с действием: подписка должна учитываться в результате запроса.

поэтому мой результат должен быть:

{"2018-10-18": 2, "2018-10-06": 1, "2018-10-17":2, "2018-10-19":1}

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

1 Ответ

0 голосов
/ 19 октября 2018

Вы должны быть в состоянии достичь этого с помощью чего-то подобного:

db.collection.aggregate([
  {
    $project: {
      events: {
        $filter: {
          input: "$events",
          as: "event",
          cond: {
            $eq: [
              "$$event.action",
              "subscribe"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: "$events"
  },
  {
    $addFields: {
      day: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: "$events.date"
        }
      }
    }
  },
  {
    $group: {
      _id: "$day",
      count: {
        $sum: 1
      }
    }
  }
])

Идея состоит в том, чтобы сначала $ filter в событиях subscribe, после чего мы $разматывать .

Затем добавьте поле дня (через $ addFields и $ dateToString ), в котором мы будем группировать на последнем этапе.

Вы можете видеть это , работающее здесь

Вы также можете добавить:

  {
    "$project": {
      "_id": 0,
      "day": "$_id",
      "count": "$count"
    }
  }

Если вы хотите получить day вместо _id

...