Sunspot: как сделать полнотекстовый запрос по нескольким полям с разными значениями? - PullRequest
5 голосов
/ 02 декабря 2011

Я бы хотел воспроизвести следующий необработанный запрос solr с помощью sunspot

q=exact_term_text:foo OR term_textv:foo* OR alternate_text:bar*

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

  1. метод fulltext, похоже, не принимает несколько аргументов text / search_fields
  2. Я не знаю, какой аргумент передать в качестве первого fulltext, как если бы я передал либо "foo", либо "bar", результаты не будут совпадать
  3. Если я передаю пустой аргумент, я получаю q=*:*
  4. фильтры контекста (например, with(:term).starting_with('foo*') (как следует из названия) применяются в качестве запросов фильтра и, таким образом, не участвуют в оценке.

Кажется возможным составить строку вручную (или, возможно, использовать adjust_solr_params), но это кажется хакерским. Есть ли лучшее решение?

Ответы [ 3 ]

8 голосов
/ 08 декабря 2011

В Sunspot 2.0.0 есть недокументированное и неподдерживаемое поведение, которое работает.Сам автор предполагает, что это не должно и, вероятно, не будет в будущих версиях.

Вы можете передать несколько полнотекстовых вызовов в определение поиска

Post.search do
    fulltext "foo", {:fields => :exact_term}
    fulltext "bar", {:fields => :alternate}
end

Это приводит к запросу solr(из журналов)

INFO: [] webapp=/solr path=/select 
params={fl=*+score&start=0&q=_query_:"{!dismax+qf%3D'exact_term'}foo"+_query_:"{!dismax+qf%3D'alternate'}bar"&wt=ruby&fq=type:Post&rows=30}
hits=1 status=0 QTime=7 

Соответствующие подстроки описаны в https://github.com/sunspot/sunspot/wiki/Matching-substrings-in-fulltext-search

Изменение оператора по умолчанию (И / ИЛИ) может быть сделано путем добавления опцииimum_match 1, как указано в http://blog.tonycode.com/archives/192

2 голосов
/ 03 октября 2013

Если документация верна, вы не можете вызвать fulltext дважды. В итоге я выполнил два поиска и вычислил пересечение обоих поисков.

a = Post.search do
    fulltext "foo", {:fields => :exact_term}
end

b = Post.search do
    fulltext "bar", {:fields => : alternate}
end

result = a & b

То, как вы вычисляете пересечение, будет зависеть от того, что именно вы пытаетесь достичь. Вышеуказанное пересечение немного наивно. Например, вы можете нормализовать оценку каждого результата по отношению к максимальному значению и использовать среднее значение нормализованной оценки для целей сортировки.

1 голос
/ 13 марта 2014

Мне также нужно иметь многократный полнотекстовый поиск для разных полей с разными значениями. Более того, мне нужно, чтобы были выполнены все условия. Другими словами, мне нужно, чтобы и 'foo', и 'bar' были в Post для точных_термов и альтернативных полей.

Post.search do
    fulltext "foo", {:fields => :exact_term}
    fulltext "bar", {:fields => :alternate}
end

Проблема заключалась в том, что я не мог изменить свои настройки schema.xml (defaultOperator). Было установлено «ИЛИ». Если у вас есть похожая проблема, вы можете обойти ее так:

Post.search do
    adjust_solr_params do |params|
        params[:q] = params[:q].gsub(/\s_query/, " AND _query") if params[:q].present?
    end
end
...