2015-02-19 4 views
0

Я пытаюсь создать систему рекомендаций, интегрируя Elasticsearch с Apache Spark. Я использую Java. В качестве примера я использую набор данных movilens. Я также проиндексировал данные в Elasticsearch. До сих пор я был в состоянии читать входные данные из индекса Elasticsearch следующим образом:Как перебирать источник Elasticsearch с помощью Apache Spark?

SparkConf conf = new SparkConf().setAppName("Example App").setMaster("local"); 
conf.set("spark.serializer", org.apache.spark.serializer.KryoSerializer.class.getName()); 
     conf.set("es.nodes", "localhost"); 
     conf.set("es.port", "9200"); 
     JavaSparkContext sc = new JavaSparkContext(conf); 
     JavaPairRDD<String, Map<String, Object>> esRDD = JavaEsSpark.esRDD(sc, "movielens/recommendation"); 

Используя функцию esRDD.collect(), я могу видеть, что я правильно извлекать данные из упругого поиска. Теперь мне нужно подать идентификатор пользователя, идентификатор элемента и предпочтение от результата Elasticsearch до рекомендации Spark. Если я использую файл CSV, я был бы в состоянии сделать это следующим образом:

String path = "resources/user_data.data"; 
     JavaRDD<String> data = sc.textFile(path); 
     JavaRDD<Rating> ratings = data.map(
      new Function<String, Rating>() { 
      public Rating call(String s) { 
       String[] sarray = s.split(" "); 
       return new Rating(Integer.parseInt(sarray[0]), Integer.parseInt(sarray[1]), 
           Double.parseDouble(sarray[2])); 
      } 
      } 
     ); 

Что может быть эквивалентным отображением, если мне нужно перебирать упругий выход поиска, хранящийся в esRDD и создать подобную карту как выше? Если есть какой-либо примерный код, на который я мог бы ссылаться, это было бы очень полезно.

ответ

1

Извиняюсь за не отвечая на вопрос Спарк непосредственно, но в случае, если вы пропустили его, есть описание делать рекомендации по данным MovieLens использованием elasticsearch здесь: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_significant_terms_demo.html

+0

Спасибо за ваше предложение. Я использовал https://github.com/codelibs/elasticsearch-taste плагин, прежде чем использовать функции рекомендации для элемента Mahout. Проблема, с которой я столкнулась, заключалась в том, что каждый пользователь имел различный уровень доступа к данным. Один пользователь может не иметь доступа ко всему набору данных и, следовательно, рекомендация для них должна быть изнутри набора данных, к которому у них есть доступ. Я не мог понять, как это сделать с этим плагином. У вас есть опыт работы с этим плагином? Я не заглянул в функцию significant_terms, теперь изучит его. –

+0

После изучения функции significant_term кажется, что он подходит, если есть четко определенное предпочтение (например, фильм понравился или нет). Но для меня ценность предпочтений пользователя имеет большое значение. Пользовательские предпочтения не просто вычисляются на основе того, нравится ли пользователю фильм или нет, но и по другим другим факторам. Можно ли учитывать такие соображения при использовании значащих_значений? –

+0

Когда я использовал significant_terms в этом наборе данных, я решил проиндексировать каждого пользователя со списком фильмов, которые им понравились (рейтинги 4 или 5 звезд). Это, казалось, давало хорошие рекомендации при представлении единого идентификатора фильма и анализе всех таких пользователей. – MarkH

0

Вы не указали формат данных в ElasticSearch , Но предположим, что у него есть поля userId, movieId и rating, поэтому пример документа выглядит примерно как {"userId":1,"movieId":1,"rating":4}.

Тогда вы должны быть в состоянии сделать (без учета пустых чеков и т.д.):

JavaRDD<Rating> ratings = esRDD.map(
    new Function<Map<String, Object>, Rating>() { 
     public Rating call(Map<String, Object> m) { 
       Int userId = Integer.parseInt(m.get("userId")); 
       Int movieId = Integer.parseInt(m.get("movieId")); 
       Double rating = Double.parseDouble(m.get("rating")); 
       return new Rating(userId, movieId, rating); 
     } 
    } 
); 
+0

Благодарим за решение. Но формат данных выглядит следующим образом: {user_id = 26, items = [{item_id = 1123, value = 0.39811674}, {item_id = 445, value = 0.13920784}, {item_id = 1129, value = 0.12835233}}, так что это не Карта , но JavaPairRDD >. Любая идея, как разобрать эту? –

+0

JavaRDD <Карта > esRDDVal = esRDD.values ​​(); Это все, что мне нужно было сделать, и использовать итерацию, как описано выше. Он работает сейчас. Благодарю. –

Смежные вопросы