MongoMapper Избегает вызывать N 1 запросов в Ruby on Rails

#ruby-on-rails #ruby #mongodb #eager-loading #mongomapper

#ruby-on-rails #ruby #mongodb #загрузка с нетерпением #mongomapper

Вопрос:

Итак, у меня есть два класса, которые выглядят так

 class Branch
  include MongoMapper::Document

  many :builds
end

class Build
  include MongoMapper::Document

  belongs_to :branch
end
  

И если мы хотим получить доступ Branch к данным из Build класса. Я могу сделать это, как показано ниже

 builds = Build.where(___)

builds.each do |build|
  puts "#{build.branch.name} build number #{build.number}"
end
  

Но это вызывает предупреждение, вызывающее N 1 запросов, потому что оно создает слишком много независимых запросов к базе данных. Ну, решение заключается в использовании нетерпеливой загрузки, как показано ниже

 builds = Build.where(____).includes(:branches)

builds.each do |build|
  puts "#{build.branch.name} build number #{build.number}"
end
  

Ну, нетерпеливая загрузка или .includes() недоступны в MongoMapper, как я смотрю из их документации (надеюсь, я ошибаюсь). Но он доступен в MongoId. Но пока я не планирую переходить с MongoMapper на MongoId. Знаете ли вы, как это сделать? это, возможно, может уменьшить количество запросов.

Ответ №1:

Согласно документам Mongoid #includes «…Загрузит все документы в карту идентификации, идентификаторы которых совпадают на основе дополнительного запроса для идентификаторов «.

Таким образом, в этом нет никакой магии — похоже, он просто выполняет дополнительный запрос для извлечения связанных объектов и сохранения их в памяти в какой-то структуре данных с O (1) чтениями (например, хэш в Ruby).). Вы можете сделать это самостоятельно (отказ от ответственности: в качестве ссылки используется псевдокод, а не готовое решение):

 builds = #...
branches = Branch.where(id: builds.map(amp;:id)).to_h { |br| [br.id, br] }

builds.each do |build|
  puts "#{branches[build.branch_id]amp;.name} build number #{build.number}"
end
  

Но, пожалуйста, обратите внимание: если вам приходится часто выполнять такого рода запоминание, это может быть сигналом о том, что модель данных не является оптимальной для базы данных на основе документов — внедренные документы могут быть более эффективным решением…