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

Mongo Map-Reduce To Mimic count(distinct(...)) group by w SQL

Możesz łatwo zagregować wynik, zamiast decydować się na rozwiązanie z redukcją mapy:

  • Match rekordy, w których data jest większa niż równa podanej dacie.

  • Group na podstawie brand_id pole.

  • Użyj $addToSet operator do obsługi products lista unikalnychproduct_id dla każdej grupy.

  • Project count products w każdym klawiszu.

Kod:

db.collection.aggregate([
{$match:{"date":{$gte:new Date('2014-11-20')}}},
{$group:{"_id":"$brand_id","products":{$addToSet:"$product_id"}}},
{$project:{"_id":0,"brand_id":"$_id","distinct_prod":{$size:"$products"}}}
])

Przechodząc do rozwiązania do redukcji map,

Jest to jeden ze sposobów, w jaki mongodb może wywołać funkcję Reduce dla każdej grupy. Z dokumentacji :

Musisz dokonać pewnych modyfikacji map ,reduce funkcje i dodaj nowy finalize funkcja:

  • Musisz o tym pamiętać, gdy mongodb wywołuje reduce funkcji dla tego samego klucza więcej niż raz, wynik poprzedniego wywołania jest przekazywany jako dane wejściowe do funkcji Reduce, wraz z innymi wartościami przy następnym wywołaniu funkcji Reduce.
  • Pierwszy punkt, musisz więc upewnić się, że dane wejściowe funkcji Reduce i wartość zwracana przez funkcję Reduce są podobnie skonstruowane, tak aby logika napisana wewnątrz funkcji Reduce umożliwiała przetwarzanie własnej wartości zwracanej w jej poprzednich wywołaniach.
  • Ponieważ nie bylibyśmy w stanie pobrać liczby odrębnych wartości w przypadku wywołania w partiach, możemy napisać reduce funkcja, która gromadzi różne product_ids dla każdego klucza i napisz finalize funkcja, która oblicza liczbę tych unikalnych wartości.

Kod:

db.collection.mapReduce(
    function() {
        // emitting the same structure returned by the reduce function.
        emit(this.brand_id, {"prod_id":[this.product_id]});
    },
    function(key, values) {
       // the return value would be a list of unique product_ids.
        var res = {"prod_id":[]};
        for(var i=0;i<values.length;i++)
        {
         for(var j=0;j<values[i].prod_id.length;j++){
            if(res.prod_id.indexOf(values[i].prod_id[j]) == -1){
                res.prod_id.push(values[i].prod_id[j]);
            }
        }}
        return res;
    },
    {
        query: {date: {$gte: new Date('2014-11-20')}},
        out: "example",
        finalize: function(key, reducedValue){
            // it returns just the count
            return reducedValue.prod_id.length;
        }
    }
)



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB C#:Update.pullAll nie usuwa elementów

  2. Dlaczego MongoDB zajmuje tyle miejsca?

  3. Odświeżanie strony Meteor za pomocą kliknięcia przycisku

  4. mongodb:Struktura indeksowania wielokluczowego?

  5. Jak korzystać z optymistycznego blokowania w Spring Data MongoDB?