Использование солнечных пятен для поиска нескольких полей разных типов в одной модели

Я добавляю поиск в свое приложение rails с драгоценным камнем sunspot, и я хотел бы иметь возможность искать транзакции по идентификатору, сумме или описанию. Поиск по одному атрибуту работает нормально, но когда я добавляю несколько вызовов with или fulltext в блок поиска, я не получаю никаких результатов. Я обнаружил, что могу обернуть вызовы with в блок any_of, но включение fulltext вызывает ошибку undefined method 'fulltext' for #<Sunspot::DSL::Scope:0x007fb6519c13a0>.

Поиск возвращает правильные результаты, когда я ищу только по 1 атрибуту, то есть у меня есть только 1 с или 1 полный текст в блоке any_of. Поэтому я должен искать по идентификатору, количеству и описанию индивидуально. Это означает, что если есть транзакция с идентификатором 213, поиск 213 возвращает транзакцию с идентификатором 213. Если я ищу 4,25 доллара, то результаты возвращают каждую транзакцию на сумму 4,25 доллара. Если я ищу «Starbucks», я получаю каждую транзакцию со словом «Starbucks» в описании. Если у меня есть несколько with или fulltext внутри любого блока, я не получаю никаких результатов.

Что мне не хватает?

У меня есть модель транзакции:

class Transaction < ActiveRecord::Base
  ...

  searchable do
    text :description
    integer :id
    float :amount
  end

  ...
end

И действие в контроллере так:

def search
  @search = Transaction.search do
    any_of do
      with(:amount, params[:search])
      with(:id, params[:search])
      fulltext(params[:search])
    end
  end

  @transactions = @search.results  
end

person J Set    schedule 29.04.2016    source источник
comment
как это "сломать"? выдает ли это ошибку, не возвращает результатов, возвращает неверные результаты и т. д. Можете ли вы опубликовать, что такое params[:search] и можете ли вы убедиться, что у вас действительно есть модель с полем description, которое содержит этот поиск   -  person PhilVarg    schedule 30.04.2016
comment
Я обновил вопрос с ошибкой и более подробной информацией. Мне нужно знать, как искать несколько полей разных типов в одной модели, поэтому ошибка, вероятно, синтаксическая. У меня есть модель транзакции с полем описания.   -  person J Set    schedule 01.05.2016


Ответы (2)


Sunspot не предназначен для поиска в нетекстовых полях. Другие типы полей дата/целое число/и т. д. могут использоваться для определения области поиска перед полнотекстовым поиском.

Как вы задали вопрос, это невозможно с солнечным пятном.

В этом примере вы можете увидеть, как поле с плавающей запятой amount используется для определения области перед полнотекстовым поиском.

def search
  @search = Transaction.search do
    with(:amount).greater_than(params[:amount])
    fulltext params[:search] do
      fields :description
    end
  end.results
end

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

person bigtunacan    schedule 02.05.2016
comment
Когда я добавляю поле, которое не имеет строкового типа, в полнотекстовый блок, я получаю текстовое поле «Нет», настроенное для транзакции с ошибкой «сумма имени». - person J Set; 02.05.2016
comment
Извините, я неправильно понял, о чем вы спрашивали. Я обновил свой ответ. - person bigtunacan; 02.05.2016
comment
Извините, я не объяснил ясно. Допустим, в Starbucks есть транзакция на 5 долларов. Я хочу, чтобы эта транзакция была в результатах поиска, если пользователь ищет «Starbucks» и/или «5.00». Это предполагает, что sunspot достаточно умен, чтобы увидеть, что params[:search] может быть текстом и/или числом, и будет использовать числа для поиска количества или идентификатора. - person J Set; 02.05.2016

Так что бигтунакан прав. Поиск в нетекстовых полях невозможен. В документации говорится:

текстовые поля будут доступны для полнотекстового поиска. Другие поля (например, целое число и строка) могут использоваться для определения области запросов.

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

Итак, в моей модели транзакций у меня есть:

# we have to create an alias because sunspot uses 'id' for something
alias_attribute :transaction_id, :id

searchable do  
  text :transaction do
    "#{description} #{amount} #{transaction_id}"
  end
end

И в моем контроллере транзакций у меня есть:

def search
  search = Transaction.search do
    fulltext(params[:search])
  end

  @transactions = search.results
end

Так что теперь я могу искать по описанию, идентификатору или сумме.

person J Set    schedule 03.05.2016