Это больше идея, чем полное решение, и я еще не тестировал ее.
Вы можете начать с извлечения конвейера обработки данных в функцию.
def pipeline(f: String, n: Int) = {
sqlContext
.read
.format("com.databricks.spark.csv")
.option("header", "true")
.load(f)
.repartition(n)
.groupBy(...)
.agg(...)
.cache // Cache so we can force computation later
}
Если ваши файлы малы, вы можете отрегулировать параметр n
, чтобы использовать как можно меньшее количество разделов для соответствия данным из одного файла и избегать перетасовки. Это означает, что вы ограничиваете параллелизм, но мы вернемся к этой проблеме позже.
val n: Int = ???
Затем вам нужно получить список входных файлов. Этот шаг зависит от источника данных, но большую часть времени он более или менее прост:
val files: Array[String] = ???
Затем вы можете сопоставить вышеуказанный список с помощью функции pipeline
:
val rdds = files.map(f => pipeline(f, n))
Поскольку мы ограничиваем параллелизм на уровне одного файла, который мы хотим компенсировать, отправив несколько заданий. Давайте добавим простой помощник, который заставляет оценивать и обертывает его с помощью Future
import scala.concurrent._
import ExecutionContext.Implicits.global
def pipelineToFuture(df: org.apache.spark.sql.DataFrame) = future {
df.rdd.foreach(_ => ()) // Force computation
df
}
. Наконец, мы можем использовать вспомогательный помощник на rdds
:
val result = Future.sequence(
rdds.map(rdd => pipelineToFuture(rdd)).toList
)
В зависимости от вашего требования вы можете добавить onComplete
обратные вызовы или использовать реактивные потоки для сбора результатов.
Только для уборки вещей немного в миграции можно теперь также сделать:
create_table :videogames do |t|
t.belongs_to :developer
t.belongs_to :publisher
end
И так как Вы называете ключи developer_id и publisher_id, модель должна, вероятно, быть:
belongs_to :developer, :class_name => "Company"
belongs_to :publisher, :class_name => "Company"
Это не основная проблема, но я нахожу, что, поскольку число связей с дополнительными аргументами добавляется, менее ясные вещи становятся, поэтому лучше придерживаться значений по умолчанию, когда это возможно.
Я понятия не имею, как сделать, это с пишет сценарий/генерирует.
базовую идею легче показать без использования, пишут сценарий/генерируют так или иначе. Вы хотите два поля в своей таблице/модели видеоигр, которые удерживают внешние клавиши к таблице/модели компаний.
я покажу Вам, что я думаю , код был бы похож, но я не протестировал его, таким образом, я мог быть неправым.
Ваш файл миграции имеет:
create_table :videogames do |t|
# all your other fields
t.int :developer_id
t.int :publisher_id
end
Тогда в Вашей модели:
belongs_to :developer, class_name: "Company", foreign_key: "developer_id"
belongs_to :publisher, class_name: "Company", foreign_key: "publisher_id"
Вы также упоминаете, что желали, чтобы эти две компании были отличны, который Вы могли обработать в проверке в модели, которая проверяет это developer_id != publisher_id
.
Если существуют какие-либо методы или проверка, Вы хотите характерный для определенного типа компании, Вы могли sub класс модель компании. Это использует технику, названную единственным наследованием таблицы. Для получения дополнительной информации проверьте эту статью: http://wiki.rubyonrails.org/rails/pages/singletableinheritance
Вы тогда имели бы:
#db/migrate/###_create_companies
class CreateCompanies < ActiveRecord::Migration
def self.up
create_table :companies do |t|
t.string :type # required so rails know what type of company a record is
t.timestamps
end
end
def self.down
drop_table :companies
end
end
#db/migrate/###_create_videogames
class CreateVideogames < ActiveRecord::Migration
create_table :videogames do |t|
t.belongs_to :developer
t.belongs_to :publisher
end
def self.down
drop_table :videogames
end
end
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :videogames
common validations and methods
end
#app/models/developer.rb
class Developer < Company
developer specific code
end
#app/models/publisher.rb
class Publisher < Company
publisher specific code
end
#app/models/videogame.rb
class Videogame < ActiveRecord::Base
belongs_to :developer, :publisher
end
В результате у Вас была бы Компания, модели Developer и Publisher для использования.
Company.find(:all)
Developer.find(:all)
Publisher.find(:all)