MongoDB MapReduce-emituje jeden klucz/jedną wartość nie zmniejsza wywołania

Więc jestem nowy z mongodb i mapreduce w ogóle i natknąłem się na to " dziwactwo "(lub przynajmniej w moim umyśle dziwactwo)

Powiedzmy, że w mojej kolekcji mam takie obiekty:

{'klucz': 5, 'wartość': 5}

{'klucz':5, 'wartość': 4}

{'klucz': 5, 'wartość': 1}

{'klucz': 4, 'wartość': 6}

{'klucz': 4, 'wartość': 4}

{'klucz': 3, 'wartość': 0}

My map funkcja po prostu emituje klucz i wartość

My reduce funkcja po prostu dodaje wartości I {[20] } przed zwróceniem dodaje 1 (zrobiłem to, aby sprawdzić, czy funkcja reduce jest nawet wywołana)

Moje wyniki:

{'_id': 3, 'wartość': 0}

{"_id": 4, "value": 11.0}

{"_id": 5, "value": 11.0}

Jak widać, za klucze 4 i 5 dostaję oczekiwaną odpowiedź 11, ale za klucz 3 (z tylko jednym wpisem w zbiorze z tym kluczem) dostaję nieoczekiwane 0!

Czy to naturalne zachowanie mapreduce w ogóle? Dla MongoDB? Do pymongo (którego używam)?

Author: IamAlexAlright, 2012-06-13

5 answers

Funkcja zmniejsz łączy dokumenty z tym samym kluczem w jeden dokument. Jeśli funkcja map emituje pojedynczy dokument dla określonego klucza (jak to ma miejsce w przypadku klucza 3), funkcja reduce nie zostanie wywołana.

 35
Author: Jenna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-13 19:32:43

Zdaję sobie sprawę, że to starsze pytanie, ale doszedłem do niego i czułem, że nadal nie rozumiem, dlaczego takie zachowanie istnieje i jak zbudować mapę / zmniejszyć funkcjonalność, więc nie jest to problem.

Powodem, dla którego MongoDB nie wywołuje funkcji reduce, jeśli istnieje pojedyncza instancja klucza, jest to, że nie jest to konieczne(mam nadzieję, że za chwilę będzie to miało sens). Poniżej znajdują się Wymagania dla funkcji redukcji :

  • funkcja reduce musi zwracać obiekt którego typ musi być identyczny z typem wartości emitowanej przez funkcję map.
  • kolejność elementów w wartościach nie powinna mieć wpływu na wyjście funkcji reduce
  • funkcja reduce musi być idempotentna.

Pierwszy wymóg jest bardzo ważny i wydaje się, że wiele osób go przeoczyło, ponieważ widziałem wiele osób mapujących w funkcji reduce, a następnie zajmujących się pojedynczym kluczem w finalize funkcja. Jest to jednak niewłaściwy sposób rozwiązania tego problemu.

Pomyśl o tym tak: jeśli istnieje tylko jedna instancja klucza, prostą optymalizacją jest całkowite pominięcie reduktora (nie ma nic do zmniejszenia). Wartości z jednym kluczem są nadal uwzględniane w wyjściu, ale celem reduktora jest zbudowanie zagregowanego wyniku dokumentów z wieloma kluczami w kolekcji. Jeśli mapper i reduktor wyprowadzają ten sam typ, powinieneś być błogiej nieświadomości patrząc na struktura obiektu wyjścia z funkcji map/reduce. Nie powinieneś używać funkcji finalize do korygowania struktury obiektów, które nie przeszły przez reduktor.

Krótko mówiąc, wykonaj mapowanie w funkcji mapy i zmniejsz wartości wielu klawiszy do jednego, zagregowanego wyniku w funkcji zmniejsz.

 4
Author: senfo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-04 01:56:04

Rozwiązanie:

  • Dodano nowe pole w map : single: 0
  • in reduce zmień to pole na: single: 1
  • In finalize make checking for this field and make required actions

    $map = new MongoCode("function() {
        var value = {
            time: this.time,
            email_id: this.email_id,
            single: 0
        };
    
        emit(this.email, value);
    }");
    
    $reduce = new MongoCode("function(k, vals) {
    
        // make some need actions here
        return {
            time: vals[0].time,
            email_id: vals[0].email_id,
            single: 1
        };
    }");
    
    $finalize = new MongoCode("function(key, reducedVal) {
        if (reducedVal.single == 0) {
            reducedVal.time = 11111;
        }
        return reducedVal;
    };");
    
 3
Author: Alexander Suvorov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-22 13:18:45

"MongoDB nie wywoła funkcji reduce dla klucza, który ma tylko jedną wartość. Argument values jest tablicą, której elementy są obiektami wartości, które są "mapowane" do klucza."

Http://docs.mongodb.org/manual/reference/command/mapReduce/#mapreduce-reduce-cmd

 1
Author: ftaher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 20:00:33

Czy to naturalne zachowanie mapreduce w ogóle?

Tak.
 0
Author: Marco Sero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-13 19:44:13