Как отфильтровать по ключу, найти по диапазону дат, а затем агрегировать по неделям в mongodb?

У меня есть коллекция монго с именем MyCollection, состоящая из документов, которые выглядят так:

{ 
    "_id" : ObjectId("58085384e4b0f70605461e3f"), 
    "uid" : "fa1aeafc-18db-41a5-8ee5-ac0c32428fe1",
    "Key1" : "Value1"  
    "timeStamp" : ISODate("2016-08-23T17:58:20.000+0000"), 
}

У одних документов есть Key1, а у других — Key2 или Key3.

Теперь я хочу сделать следующее: -

  1. Получите только те документы, которые имеют Key1 или Key2.
  2. Из результирующего набора документов выше выберите только те документы, которые находятся в диапазоне timeStamp от Date(2016, 08, 01) до Date(2016, 08, 31).
  3. Для получившегося набора документов выше объедините их по неделям.

Как мне написать запрос монго для этого?


person Train Heartnet    schedule 14.03.2017    source источник


Ответы (2)


Используя структуру агрегации, указанные выше шаги можно выполнить с помощью $match и $group конвейер выполняет следующие шаги:

var start = new Date(2016, 7, 1), // months are zero-based indexes i.e Aug month index is 7
    end = new Date(2016, 7, 30); // August month ends on the 30th

db.collection.aggregate([
    { /* filter steps 1 & 2 */
        "$match": {
            "$or": [
                { "Key1": { "$exists": true } },
                { "Key2": { "$exists": true } }
            ],
            "timeStamp": { "$gte": start, "$lte": end }
        }
    },
    { /* group by week */ 
        "$group": {
            "_id": { "$week": "$timeStamp" },
            "count": { "$sum": 1 },
            "uids": { "$push": "$uid" }
        }
    }
])

В приведенном выше примере диапазон дат создается с помощью Date(), где месяцы — это индексы, отсчитываемые от нуля. Оператор $exists используется для определить наличие ключа и использовать $week агрегатный оператор даты, чтобы получить номер недели в дате от 0 (неполная неделя, предшествующая первому воскресенью года) до 53 (високосный год).

Для номеров недель, начинающихся с 1 с недели (с понедельника по воскресенье), которая содержит первый четверг года, MongoDB 3.4 и новее предоставили $isoweek для использования.

person chridam    schedule 14.03.2017

попробуй это:

db.collection.find(
{$or:[{"key1":{$exists:true}},{"key2":{$exists:true}}],
timeStamp: {$gte: Date(2016, 08, 01), $lte:Date(2016, 08, 31)}
})

вышеприведенный запрос выполнил ваши 1 и 2 условия. Каково ваше 3-е условие, я не совсем понимаю, пожалуйста, уточните.

person Vaibhav Patil    schedule 14.03.2017