Как создать ссылки между вершинами в RDD[(Long, Vertex)] на основе свойства?

У меня есть пользователи: RDD[(Long, Vertex)] коллекция пользователей. Я хочу создать связи между моими объектами Vertex. Правило такое: если две вершины имеют одинаковое значение в выбранном свойстве - назовите его prop1, то связь существует.

Моя проблема заключается в том, как проверить каждую пару в одной коллекции. Если я сделаю:

val rels = users.map(
  x => users.map(y => if(x._2.prop1 == y._2.prop1){(x._1, y._1)}))

Я получил RDD[RDD[Any]], а не RDD[(Long, Long)], как ожидалось, чтобы график работал.


person user299791    schedule 19.11.2015    source источник
comment
Вы должны написать блок else для своего, если так, то результирующий тип будет (Long, Long) - одна из проблем   -  person Nyavro    schedule 19.11.2015
comment
Знаете ли вы другой способ связать вместе людей, которые имеют общий атрибут?   -  person user299791    schedule 19.11.2015
comment
извините, но я не понимаю ваш предыдущий комментарий, другого нет, если они не совпадают, ссылка не должна возвращаться   -  person user299791    schedule 19.11.2015
comment
Если вы не укажете оператор else, тип результата будет Any, как вы указали RDD[RDD[Any]]. Поэтому, если у вас нет оператора else, вам лучше использовать фильтр коллекции по свойству equal   -  person Nyavro    schedule 19.11.2015
comment
Я бы сгруппировал коллекцию пользователей по prop1. И получить желаемые пары из групп   -  person Nyavro    schedule 19.11.2015


Ответы (1)


Прежде всего, вы не можете запустить действие преобразования из другого действия или преобразования, не говоря уже о создании вложенных RDDs. Так что просто невозможно получить RDD[RDD[Any]].

Здесь вам, скорее всего, нужно простое соединение, примерно эквивалентное чему-то вроде этого, где T — это тип property1:

val pairs: RDD[(T, Long)] = users.map{ case (id, v) => (v.prop1, id) }
val links: RDD[(Long, Long)] = pairs
  .join(pairs)  // join by a common property, equivalent to INNER JOIN in SQL
  .values  // drop properties
  .filter{ case (v1, v2) => v1 != v2 }  // filter self-links
person zero323    schedule 19.11.2015
comment
спасибо за ответ, я сообщаю RDD[RDD[Any]] как следствие предупреждения об ошибке Eclipse: несоответствие типов; найдено: org.apache.spark.rdd.RDD[org.apache.spark.rdd.RDD[Any]] требуется: org.apache.spark.rdd.RDD[org.apache.spark.graphx.Edge[?]] Произошла ошибка в приложении с аргументами по умолчанию. - person user299791; 19.11.2015
comment
Да, никогда не верьте IDE :) - person zero323; 19.11.2015
comment
так что теперь я понимаю, что вы не были ироничными в своем сообщении, извините за чрезмерную реакцию ... :) - person user299791; 19.11.2015
comment
Не беспокойтесь... Тем не менее, это Spark 101, и дело не только в сопоставлении типов. Если бы не это, вы могли бы просто заменить внешний map на flatMap внутренний map на filter. - person zero323; 19.11.2015
comment
@digitaldust Спасибо, исправлено. - person zero323; 19.11.2015
comment
Я только что понял, что результат должен быть в форме Edge (3L, 7L, Collab), поэтому что-то вроде RDD [Edge []] для подачи конструктору graphx... Я все равно приму ваш ответ, потому что он идеально подходит для моего фактического вопроса - person user299791; 19.11.2015
comment
Вы можете просто добавить еще один map после фильтра. Если вы хотите сохранить свойство и использовать его в качестве метки края, удалите values вызов фильтра/карты напрямую. - person zero323; 19.11.2015