Этап сокращения MongoDB не работает должным образом

1

Я работал с java-учебником для mapReduce-Programming в MongoDB и получил следующий код:

package mapReduceExample;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceOutput;
import com.mongodb.Mongo;

public class MapReduceExampleMain {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Mongo mongo;

        try {
            mongo = new Mongo("localhost", 27017);
            DB db = mongo.getDB("library");

            DBCollection books = db.getCollection("books");

            BasicDBObject book = new BasicDBObject();
            book.put("name", "Understanding JAVA");
            book.put("pages", 100);
            books.insert(book);

            book = new BasicDBObject();
            book.put("name", "Understanding JSON");
            book.put("pages", 200);
            books.insert(book);

            book = new BasicDBObject();
            book.put("name", "Understanding XML");
            book.put("pages", 300);
            books.insert(book);

            book = new BasicDBObject();
            book.put("name", "Understanding Web Services");
            book.put("pages", 400);
            books.insert(book);

            book = new BasicDBObject();
            book.put("name", "Understanding Axis2");
            book.put("pages", 150);
            books.insert(book);

            String map = "function()"
                    + "{ "
                        + "var category; "
                        + "if ( this.pages > 100 ) category = 'Big Books'; "
                        + "else category = 'Small Books'; "
                        + "emit(category, {name: this.name});"
                    + "}";

            String reduce = "function(key, values)"
                    + "{"
                        + "return {books: values.length};"
                    + "} ";

            MapReduceCommand cmd = new MapReduceCommand(books, map, reduce,
                    null, MapReduceCommand.OutputType.INLINE, null);

            MapReduceOutput out = books.mapReduce(cmd);

            for (DBObject o : out.results()) {
                System.out.println(o.toString());
            }

            //aufräumen
            db.dropDatabase();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
}

Это довольно простая фаза сокращения, но это не то, что я хочу :(

Выход:

{ "_id" : "Big Books" , "value" : { "books" : 4.0}}
{ "_id" : "Small Books" , "value" : { "name" : "Understanding JAVA"}}

Я ожидал бы этого:

{ "_id" : "Big Books" , "value" : { "books" : 4.0}}
{ "_id" : "Small Books" , "value" : { "books" : 1.0}}

Почему сокращение-фаза не возвращает значения.length в случае небольшой книги?

Привет, Андре

Теги:
mapreduce

2 ответа

1
Лучший ответ

Becuase, если есть только один результат, сокращение никогда не запускается. Измените его как функцию финализации или что-то в этом роде.

1

Основное понимание того, как работает mapReduce


Введем понятия mapReduce

  • mapper - это этап, на котором испускаются данные, которые нужно подавать на сцену уменьшения. Для этого требуется ключ и значение. Вы можете испускать несколько раз, если хотите, в mapper, но требования остаются неизменными.

  • редуктор - редуктор вызывается, когда имеется более одного значения заданного ключа для обработки списка значений, которые были выбраны для этого ключа.


Тем не менее, поскольку картограф выпустил только одно ключевое значение, ваш редуктор не был вызван.

Вы можете очистить это до финализации, но поведение испускания из картографа, проходящего прямо через стандартную конструкцию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню