MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

oblicz częstotliwość za pomocą agregowanego frameworka mongodb

Jeśli chodzi tylko o uzyskanie wyników w odstępach 10-sekundowych, możesz trochę policzyć i przeprowadzić to przez agregację:

db.collection.aggregate([
    { "$group": {
        "_id": {
             "year": { "$year": "$created_at" },
             "month":{ "$month": "$created_at" },
             "day": { "$dayOfMonth": "$created_at" },
             "hour": { "$hour": "$created_at" },
             "minute": { "$minute": "$created_at" },
             "second": { "$subtract": [
                 { "$second": "$created_at" },
                 { "$mod": [
                     { "$second": "$created_at" },
                     10
                 ]}
             ]}
        },
        "count": { "$sum" : 1 }
    }}
])

To rozkłada rzeczy na interwały 10 sekund na minutę, w których występują przy odrobinie matematyki mod 10.

Myślę, że to rozsądne i byłbym najszybszym biegaczem, ponieważ używa kruszywa. Jeśli naprawdę potrzebujesz, aby sekwencja, jak pokazano, trwała 10 sekund od początkowo dopasowanego czasu, możesz wykonać ten proces za pomocą mapReduce:

Najpierw twórca map:

var mapper = function () {

    if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
        if ( last_date == 0 ) {
            last_date = this.created_at.getTime();
        } else {
            last_date += 10000;
        }
    }

    emit(
        {
            start: new Date( last_date ),
            end: new Date( last_date + 10000 )
        },
        this.created_at
    );

}

To spowoduje wyemitowanie dat w przedziale 10 sekund, zaczynając od pierwszej daty, a następnie zwiększając interwał za każdym razem, gdy coś znajdzie się poza zakresem

Teraz potrzebujesz reduktora:

var reducer = function (key, values) {
    return values.length;
};

Bardzo prosta. Po prostu zwróć długość przekazanej tablicy.

Ponieważ mapReduce działa tak, jak działa, wszystko, co nie ma więcej niż jednej wartości, nie jest przekazywane do reduktora, więc posprzątaj to za pomocą finalize:

var finalize = function (key, value) {
    if ( typeof(value) == "object" ) {
        value = 1;
    }
    return value;
};

Następnie po prostu uruchom go, aby uzyskać wyniki. Zwróć uwagę na sekcję „scope”, która przekazuje zmienną globalną, która ma być używana w programie mapującym:

db.collection.mapReduce(
    mapper,
    reducer,
    { 
        "out": { "inline": 1 }, 
        "scope": { "last_date": 0 }, 
        "finalize": finalize 
    }
)

Każde podejście prawdopodobnie da nieco inne wyniki, ale o to właśnie chodzi. To zależy od tego, którego faktycznie chcesz użyć.

Biorąc pod uwagę Twój komentarz, możesz albo „sprawdzić” wyniki z obu stwierdzeń i „uzupełnić luki” niejako programowo. Generalnie wolę tę opcję, ale to nie jest mój program i nie wiem, jak dużą serię próbujesz pobrać z tego zapytania.

Po stronie serwera możesz załatać „mappera”, aby zrobić coś takiego:

var mapper = function () {

    if ( this.created_at.getTime() > ( last_date + 10000 ) ) {

        if ( last_date == 0 ) {
            last_date = this.created_at.getTime();
        } else {
            // Patching for empty blocks
            var times = Math.floor( 
                 ( this.created_at.getTime() - last_date ) / 10000
            );

            if ( times > 1 ) {
                for ( var i=1; i < times; i++ ) {
                    last_date += 10000;
                    emit(
                        {
                            start: new Date( last_date ),
                            end: new Date( last_date + 10000 )
                        },
                        0
                    );
                }
            }
            // End patch
            last_date += 10000;
        }
    }

    emit(
        {
            start: new Date( last_date ),
            end: new Date( last_date + 10000 )
        },
        this.created_at
    );

}



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Funkcja platformy Azure nie zwraca wyniku

  2. Eksportuj prawidłowy json z kolekcji mongodb

  3. mangusta _id pola nie można usunąć

  4. Jak pobrać datę z MongoDB ObjectId za pomocą SQL?

  5. Różnica MongoDB między kodem błędu 11000 i 11001