ruby-on-railsrubysunspotsunspot-railssunspot-solr

Search for empty string field in Sunspot (Solr)


In my model, I'm simply using something like:

class Person < ActiveRecord::Base
  searchable do
    string :middle_name
  end
end

The particular object I'm trying to search for has a :middle_name attribute that contains '', an empty string and is of the String datatype. Based on that information, I am assuming that Sunspot is also saving an empty string for that field in the Solr index.

After successfully doing Person.reindex and Sunspot.commit, I tried searching for the said object using Person.search{with(:middle_name, '')}.resultsin the rails console and it returns a 400 error in regards to Solr query syntax.

I then looked around and found some information on a query like Person.search{with(:middle_name, "* TO ''")}.results and Person.search{without(:middle_name, "* TO *")}.results, both of which return an empty set: [].

Anyone know a way that actually works and/or what the best way to do this is?


Solution

  • To make it work you have make monkey patch Sunspot::Query::Restriction::EqualTo method. Create a new file in config/initializers directory and add this code:

    module Sunspot
        module Query
          module Restriction
    
              class EqualTo < Base
                  def to_positive_boolean_phrase
                      case @value
                      when nil
                         "#{escape(@field.indexed_name)}:[* TO *]"
                      when ''
                         %Q(#{escape(@field.indexed_name)}:[* TO ""])
                      else
                         super
                      end
                   end
    
                   def negated?
                      if @value.nil?
                          !super
                      else
                          super
                      end
                   end
    
                   private
    
                   def to_solr_conditional
                       "#{solr_value}"
                   end
    
               end
           end
        end
    end
    

    Remember to restart rails server before you try this.