Получение результатов MapReduce на RIAK (с помощью Java-клиента)

Я сохраняю POJO Person (4 строковых поля — id, name, lastUpdate, Data) в RIAK, а затем пытаюсь получить эти объекты с помощью MapReduce.

Я делаю это очень похоже на документацию Basho:

    BucketMapReduce m = riakClient.mapReduce("person");
    m.addMapPhase(new NamedJSFunction("Riak.mapByFields"), true);
    MapReduceResult result = m.execute();
    Collection<Person> tmp = result.getResult(Person.class);

вызывается конструктор Person's String:

public Person(String str){}

(У меня должен быть этот конструктор, иначе я получаю исключение из-за его отсутствия) Там я получаю объект как строку - поля объекта в одной строке со странным разделителем.

почему я не получаю объект, автоматически преобразованный в мой POJO? мне действительно нужно просмотреть строку и десериализовать ее? я делаю что-то не так?


person o'mac    schedule 18.07.2012    source источник


Ответы (1)


Функция JS, которую вы используете, не делает того, что вы думаете :) Она выбирает объекты на основе поля с определенным значением, которое вы должны предоставить в качестве аргумента для фазы.

Я думаю, что вы ищете mapValuesJson, который будет делать то, что вы хотите сделать.

Кроме того, вам вообще не нужен конструктор в вашем POJO.

Приведенный ниже код должен указать вам правильное направление (очевидно, это очень просто со всеми общедоступными полями в POJO и без аннотаций):

public class App {

    public static void main( String[] args ) throws IOException, RiakException
    {
        IRiakClient client = RiakFactory.httpClient();
        Bucket b = client.fetchBucket("test_mr").execute();

        b.store("myobject", new Person()).execute();
        IRiakObject o = b.fetch("myobject").execute();
        System.out.println(o.getValueAsString());


        BucketMapReduce m = client.mapReduce("test_mr");
        m.addMapPhase(new NamedJSFunction("Riak.mapValuesJson"), true);
        MapReduceResult result = m.execute();
        System.out.println(result.getResultRaw());
        Collection<Person> tmp = result.getResult(Person.class);

        for (Person p : tmp)
        {
            System.out.println(p.data);
        }


        client.shutdown();
    }
}

class Person 
{
    public String id = "12345";
    public String name = "my name";
    public String lastUpdate = "some time";
    public String data = "some data";


}
person Brian Roach    schedule 18.07.2012
comment
Привет Брайан, спасибо за ваш ответ. на самом деле я пробовал упомянутые вами функции JS, но при этом я даже не прохожу стадию выполнения. Я получаю IOException:{фаза:0,ошибка:[{‹‹\lineno\››,477},{‹‹\message\››,‹‹\JSON.parse\››},{‹‹\source \››,‹‹\unknown\››}],введите:{ok,{r_object,‹‹\new\››,‹‹\2\››,[{r_content,{dict,7.... возможно, упомянутые вами аннотации - это то, что мне не хватает? - person o'mac; 29.07.2012
comment
Похоже, что все, что вы сохранили в riak, недействительно в формате JSON; например ошибка JSON.parse (или, по крайней мере, хотя бы один элемент, который вы сохранили, недействителен). Приведенный выше код является полностью рабочим примером — аннотации не требуются; они используются, если вы хотите указать индексы, ссылки и т. д. при чтении/записи объектов. - person Brian Roach; 29.07.2012
comment
Привет, Брайан, большое спасибо! Я запускал ваш пример и получал исходное исключение: org.codehaus.jackson.map.JsonMappingException: не найден подходящий конструктор для типа [простой тип, класс com.att.cso.omss.data.riak.controllers.RiakBaseController$Personx ]: не удается создать экземпляр из объекта JSON (нужно добавить/включить информацию о типе?), затем я создал новый чистый проект с вашим кодом — и это сработало! по-видимому, некоторые старые зависимости в моем POM указывали на другую версию json, которая переопределяла ту, которая нужна RIAK. Спасибо! - person o'mac; 30.07.2012
comment
@ user1510151 - Рад, что смог помочь. Пожалуйста, проголосуйте за ответ и примите его. Кроме того, вы можете связаться с нами напрямую из списка рассылки riak-users, lists.basho.com/mailman/listinfo/riak-users_lists.basho.com — все наши инженеры отслеживают список и отвечают на него. - person Brian Roach; 30.07.2012
comment
Кстати, когда я сохраняю объект с помощью Convertor (KRYO), mapreduce не работает --> я получаю исключение десериализации. есть ли способ заставить его работать? потому что без withConvertor, сохраняющего ссылку, ходьба проблематична... - person o'mac; 02.08.2012