Ответ 1
Поддержка ассоциаций ActiveRecord в Tire работает, но требует нескольких настроек в вашем приложении. Там нет сомнений, что библиотека должна работать лучше здесь, и в будущем это, безусловно, будет.
Итак, вот полноценный пример конфигурации Tire для работы с ассоциациями Rails в elasticsearch: active_record_associations.rb
Позвольте мне выделить пару вещей здесь.
Прикосновение к родительскому
Во-первых, вы должны убедиться, что вы сообщаете родительскую модель ассоциации об изменениях в ассоциации.
Учитывая, что у нас есть модель Chapter
, которая "принадлежит" a Book
, нам нужно сделать:
class Chapter < ActiveRecord::Base
belongs_to :book, touch: true
end
Таким образом, когда мы делаем что-то вроде:
book.chapters.create text: "Lorem ipsum...."
Экземпляр Book
уведомляется о добавленной главе.
Отвечая на вопросы
При сортировке этой части нам необходимо уведомить Tire об изменении и обновить индекс elasticsearch соответственно:
class Book < ActiveRecord::Base
has_many :chapters
after_touch() { tire.update_index }
end
(Нет сомнений, что Tire должен перехватывать уведомления after_touch
сам по себе, а не заставлять вас делать это. С другой стороны, это завещание о том, как легко будет работать с ограничениями библиотеки в манере что не повредит вашим глазам.)
Соответствующая сериализация JSON в Rails < 3.1
Несмотря на упоминания README, вы должны отключить автоматическое "добавление корневого ключа в JSON" в Rails < 3.1, многие забывают об этом, поэтому вы должны включить его также в определение класса:
self.include_root_in_json = false
Надлежащее отображение для elasticsearch
Теперь идет мясо нашей работы - определение правильного отображения для наших документов (моделей):
mapping do
indexes :title, type: 'string', boost: 10, analyzer: 'snowball'
indexes :created_at, type: 'date'
indexes :chapters do
indexes :text, analyzer: 'snowball'
end
end
Обратите внимание, что мы индексируем title
с повышением, created_at
как "дата" и текст главы из связанной модели. Все данные эффективно "де-нормируются" как единый документ в поиске elastics (если такой термин имеет мало смысла).
Надлежащий документ Сериализация JSON
В качестве последнего шага нам необходимо правильно сериализовать документ в индексе elasticsearch. Обратите внимание, как мы можем использовать удобный метод to_json
из ActiveRecord:
def to_indexed_json
to_json( include: { chapters: { only: [:text] } } )
end
При всей этой настройке мы можем искать в свойствах как части Book
, так и Chapter
нашего документа.
Запустите active_record_associations.rb Файл Ruby, связанный в начале, чтобы увидеть полную картину.
Для получения дополнительной информации, пожалуйста, обратитесь к этим ресурсам:
- https://github.com/karmi/railscasts-episodes/commit/ee1f6f3
- https://github.com/karmi/railscasts-episodes/commit/03c45c3
- https://github.com/karmi/tire/blob/master/test/models/active_record_models.rb#L10-20
См. этот ответ StackOverflow: ElasticSearch и Tire: использование сопоставления и to_indexed_json для получения дополнительной информации о взаимодействии mapping
/to_indexed_json
.
См. этот ответ StackOverflow: Индексируйте результаты метода в ElasticSearch (Tire + ActiveRecord), чтобы узнать, как бороться с n + 1 запросами при индексировании моделей с ассоциациями.