MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Монго агрегиране в интервали от време

Има няколко начина за подход към това в зависимост от това кой изходен формат отговаря най-добре на вашите нужди. Основната бележка е, че с "рамката за агрегиране" сама по себе си, вие всъщност не можете да върнете нещо „предадено“ като дата, но можете да получите стойности, които лесно се реконструират в Date обект при обработка на резултатите във вашия API.

Първият подход е да използвате "Оператори за агрегиране на дати" достъпни за рамката за агрегиране:

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "year": { "$year": "$time" },
            "dayOfYear": { "$dayOfYear": "$time" },
            "hour": { "$hour": "$time" },
            "minute": {
                "$subtract": [
                    { "$minute": "$time" },
                    { "$mod": [ { "$minute": "$time" }, 10 ] }
                ]
            }
        },
        "count": { "$sum": 1 }
    }}
])

Което връща съставен ключ за _id съдържащ всички стойности, които искате за "дата". Алтернативно, ако винаги в рамките на „час“ просто използвайте частта „минута“ и изчислете действителната дата въз основа на startDate от вашия избор на диапазон.

Или можете просто да използвате обикновена "Date math", за да получите милисекундите от "epoch", които отново могат да бъдат подавани директно към конструктор на дата.

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "$subtract": [
               { "$subtract": [ "$time", new Date(0) ] },
               { "$mod": [
                   { "$subtract": [ "$time", new Date(0) ] },
                   1000 * 60 * 10
               ]}
            ]
        },
        "count": { "$sum": 1 }
    }}
])

Във всички случаи това, което винеправите което искате да направите, е да използвате $project преди действителното прилагане на $group . Като „етап на тръбопровода“, $project трябва да "циклира" през всички избрани документи и да "трансформира" съдържанието.

Това отнема време и добавя към общия брой на изпълнението на заявката. Можете просто да кандидатствате към $group директно, както е показано.

Или ако сте наистина "чисти" относно Date обектът се връща без последваща обработка, тогава винаги можете да използвате "mapReduce" , тъй като функциите на JavaScript всъщност позволяват преработване като дата, но по-бавно от рамката за агрегиране и разбира се без отговор на курсора:

db.collection.mapReduce(
   function() {
       var date = new Date(
           this.time.valueOf() 
           - ( this.time.valueOf() % ( 1000 * 60 * 10 ) )
       );
       emit(date,1);
   },
   function(key,values) {
       return Array.sum(values);
   },
   { "out": { "inline": 1 } }
)

Най-добрият ви залог обаче е да използвате агрегиране, тъй като трансформирането на отговора е доста лесно:

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "year": { "$year": "$time" },
            "dayOfYear": { "$dayOfYear": "$time" },
            "hour": { "$hour": "$time" },
            "minute": {
                "$subtract": [
                    { "$minute": "$time" },
                    { "$mod": [ { "$minute": "$time" }, 10 ] }
                ]
            }
        },
        "count": { "$sum": 1 }
    }}
]).forEach(function(doc) {
    doc._id = new Date(doc._id);
    printjson(doc);
})

И след това имате изход за групиране на интервали с реална Date обекти.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Цикълът не извежда true или false въз основа на заявка

  2. MongoDB:как да зададете ново поле, равно на стойността на друго поле, за всеки документ в колекция

  3. Правилно използване на Electron

  4. Актуализация на MongoDB (вмъкване на списък с елементи в масив)

  5. актуализиране на n-тия документ в документ с вложен масив в mongodb