J Set
J Set

Reputation: 1210

Using sunspot to search multiple fields of different types on same model

I am adding search to my rails app with the sunspot gem and I would like to be able to search for transactions by id, amount, or description. Searching by a single attribute works fine, but when I add multiple with or fulltext calls in the search block I get no results returned. I found I can wrap the with calls in a any_of block, but including a fulltext causes a undefined method 'fulltext' for #<Sunspot::DSL::Scope:0x007fb6519c13a0> error.

Search returns the correct results when I search only on 1 attribute, meaning I only have 1 with or 1 fulltext in the any_of block. So I am to search by id, amount, and description invidually. Meaning if there is a transaction with id 213, searching for 213 returns the transaction with id 213. If I search for $4.25, then the results returns every transaction with amount $4.25. If I search for 'Starbucks', then I get every transaction with 'Starbucks' in the description. If I have multiple with or fulltext inside the anyblock I do not get any results returned.

What am I missing?

I have a transaction model like so:

class Transaction < ActiveRecord::Base
  ...

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

  ...
end

And an action in the controller like so:

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

Upvotes: 2

Views: 1053

Answers (2)

J Set
J Set

Reputation: 1210

So bigtunacan is right. It is not possible to search on non text fields. The documentation says:

text fields will be full-text searchable. Other fields (e.g., integer and string) can be used to scope queries.

But to make this work you can pass a block to the text method and sunspot will index the result of the block. So I pass in all the fields I want to search on in a string.

So in my transaction model I have:

# 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

And in my transaction controller I have:

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

  @transactions = search.results
end

So now I can search by description, id, or amount.

Upvotes: 0

bigtunacan
bigtunacan

Reputation: 4986

Sunspot is not intended to search non text fields. Other fields types date/integer/etc.. can be used to scope the search prior to the fulltext search.

As you have posed the question it is not possible with sunspot.

In this example you can see how the float field amount is used to scope prior to the fulltext search.

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

If you wanted to search non text value, you would need to change them to text values first; I can see in some cases where this would be valuable for searching, such as if you had a unique numeric userid.

Upvotes: 1

Related Questions