Search code examples
ruby-on-railsrubysolrfull-text-searchsunspot

Sunspot: how to do a fulltext query on multiple fields with different values?


I'd like to reproduce the following raw solr query with sunspot

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

but I am not able to understand if and how this is possible, through the standard sunspot interface, since it seems that:

  1. the fulltext method does not seem to accept multiple text/search_fields arguments
  2. I wouldn't know what argument to pass as the first one to fulltext, as if I pass either "foo" or "bar" the results would not match
  3. If I pass an empty argument I get a q=*:*
  4. the scope filters (e.g. with(:term).starting_with('foo*') are (as the name implies) applied as filter queries, and thus take no part in scoring.

It seems possible to hand-compose the string (or possibly use adjust_solr_params) but that seems hackish. Is there a better solution?


Solution

  • In Sunspot 2.0.0, there is undocumented and unsupported behaviour that does work. The author himself suggests it shouldn't and it probably won't in future versions.

    You can pass multiple fulltext calls into the search definition

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

    This results in a solr query of (from the logs)

    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 
    

    Matching substrings is covered in https://github.com/sunspot/sunspot/wiki/Matching-substrings-in-fulltext-search

    Changing the default operator (AND/OR) can be done by adding a option minimum_match 1 as mentioned in http://blog.tonycode.com/archives/192