sunspot solr как правильно искать несколько моделей? Все примеры онлайн провалились
Как правильно искать несколько моделей в SunSpot Solr?
Модель профиля
has_one :match
searchable do
string :country
string :state
string :city
end
Модель спички
belongs_to :profile
searchable do
string :looking_for_education
integer :age_from
integer :age_to
end
ProfilesController#Index
def index
@search = Sunspot.search Profile, Match do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education]) <= from the 2nd model
end
@profiles = @search.results
end
Это не с:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
Удаление
с (:age).between(params[:age_from]..params[:age_to]) затем пытается
Затем он пытается загрузить
view app/views/educators/educator.html.haml
который не существует (я только использую
/app/views/profiles/_profile.html.haml
показывать профили
РЕДАКТИРОВАНИЕ № 1:
Каковы хорошие проекты с открытым исходным кодом в ruby на рельсах, которые используют sunspot и solr немного более продвинутым способом, чтобы взглянуть на них? Может быть, я смогу найти ответ там. Любой ответ в этом направлении также будет принят за вознаграждение, если оно приведет к возникновению этой проблемы, спасибо!
4 ответа
Метод поиска нескольких моделей правильный. Однако, похоже, что смысл вашего поиска не в том, что вы хотели. Похоже, вы пытаетесь сказать:
Дай мне все
Profile
записи с этимиcountry
а такжеstate
ценности и чьиMatch
запись имеет этоlooking_for_education
значение
Ваш поиск, однако, говорит:
Дайте мне все записи типа
Profile
или жеMatch
которые имеют все этоcountry
,state
а такжеlooking_for_education
ценности
Потому что ни Profile
ни Match
иметь все эти поля в соответствующих searchable
блоки, ни одна запись не может соответствовать указанным вами условиям.
Если я прав относительно вашего предполагаемого поведения, указанного выше, то вам нужно включить информацию о профиле, связанную с соответствием, в профиль searchable
блок, вот так:
class Profile < ActiveRecord::Base
has_one :match
searchable do
string(:country)
string(:state)
string(:city)
string(:looking_for_education) { match.looking_for_education }
integer(:age_from) { match.age_from }
integer(:age_to) { match.age_to }
end
end
Здесь мы сказали Sunspot индексировать свойства сопоставления соответствия профиля, как если бы они жили в самом профиле. В соответствующих блоках мы рассказали Sunspot, как заполнять эти значения при индексировании профиля.
Это позволит вам написать свой поиск, используя только Profile
модель:
def index
@search = Sunspot.search Profile do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education])
with(:age).between(params[:age_from]..params[:age_to])
end
@profiles = @search.results
end
Этот поиск вернет только Profile
записи, в то же время отражая свойства сопоставления совпадений каждого профиля, потому что мы сохранили их, когда профиль был проиндексирован.
Обратите внимание, что это увеличивает сложность при индексировании ваших моделей. Если Match
Записывая изменения, соответствующий профиль теперь необходимо переиндексировать, чтобы отразить эти изменения.
@moises-zaragoza правильно ответили на ваш вопрос, но у вас больше проблем, чем вы думаете, с тем, что вы хотите сделать.
Первая ошибка:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
Скорее всего, создается потому, что params[:age_from] и / или params[:age_to] равны нулю. Я не могу заверить это, потому что вы не показали трассировку стека. Вы можете исправить с помощью фильтра только тогда, когда они присутствуют: with(:age).between(params[:age_from]..params[:age_to]) if params[:age_from].present? и params[:age_to].present?
Вторая ошибка
Связанные с вашими взглядами. Я предполагаю, что вы визуализируете коллекцию или объект с помощью одного из помощников частичного объекта помощника rails, без указания частичного (опять же, без кода это более правильное предположение, чем что-либо еще):
<%= render @results %>
или же
<% @results.each do |result| %>
<%= render result %>
<% end %>
Когда в Rails не указано частичное, оно угадывает частичное имя в зависимости от типа объекта. В этом случае, если ваш объект, например, класса Educator, который может быть подклассом Profile, Rails будет искать частичный файл educators/_educator.html.erb. Удостоверьтесь, что вы отрисовываете правильное частичное в зависимости от типа объекта, и это обеспечит вам то, что вы хотите.
Это то, что я делаю, когда мне приходится искать несколько моделей
Sunspot.search [Model1, Model2] do
....
end
Здесь ответ для поиска другой модели по соответствующей строке with
searchable(:auto_index => AppConfig.solr.auto_index) do
string :category_name, :stored => true
text :content, :stored => true
text :title
string :company_id, :stored => true
time :published_on
end
search do |q|
if params[:keyword].present?
q.fulltext params[:keyword] do
fields(:deal_data)
end
end
if (ids = params["company_id"]).present?
ids = ids.split(",")
q.with(:company_id,ids) #here company id formate should be ["***","***"]
end
end