1
votes

I just started learning to use Sunspot / Solr with Rails.

I followed this RailsCast http://railscasts.com/episodes/278-search-with-sunspot

When I have no search queries and the search field is blank, Solr is returning all results from the Article model by default.

Here's my ArticlesController#index

def index
    @search = Article.search do
      fulltext params[:search]
    end
    @articles = Article.all
    @search_results = @search.results
end

When entering no params and just "" in the search bar, the console outputs the following:

Started GET "/articles?utf8=%E2%9C%93&search=" for 127.0.0.1 at 2013-01-17 12:28:09 -0800
  Processing by ArticlesController#index as HTML
  Parameters: {"utf8"=>"✓", "search"=>""}
  SOLR Request (17.0ms)  [ path=#<RSolr::Client:0x007f9b5a6643e0> parameters={data: fq=type%3AArticle&start=0&rows=30&q=%2A%3A%2A, method: post, params: {:wt=>:ruby}, query: wt=ruby, headers: {"Content-Type"=>"application/x-www-form-urlencoded; charset=UTF-8"}, path: select, uri: http://localhost:8982/solr/select?wt=ruby, open_timeout: , read_timeout: } ]
  Article Load (0.4ms)  SELECT "articles".* FROM "articles"
  Article Load (0.4ms)  SELECT "articles".* FROM "articles" WHERE "articles"."id" IN (1, 2, 3, 4, 5, 6, 7, 8)
Rendered articles/index.html.erb within layouts/application (7.6ms)
Completed 200 OK in 74ms (Views: 10.8ms | ActiveRecord: 0.8ms | Solr: 17.0ms)
[2013-01-17 12:28:09] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

The behavior I want is for nothing to be returned unless a search term is given. I tried modifying the ArticlesController#index as follows:

def index
    if params[:search] = ""
      @search_results = []

    else
      @search = Article.search do
        fulltext params[:search]
      end
      @search_results = @search.results

    end
    @articles = Article.all
  end

With this condition, when I enter nothing in the search field so that param[:search] = "", nothing is returned from Solr, which is desired behavior.

Started GET "/articles?utf8=%E2%9C%93&search=" for 127.0.0.1 at 2013-01-18 12:02:52 -0800
  Processing by ArticlesController#index as HTML
  Parameters: {"utf8"=>"✓", "search"=>""}
  Article Load (0.5ms)  SELECT "articles".* FROM "articles"
Rendered articles/index.html.erb within layouts/application (11.1ms)
Completed 200 OK in 23ms (Views: 14.1ms | ActiveRecord: 0.5ms | Solr: 0.0ms)
[2013-01-18 12:02:52] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

However, when I enter the search term "ruby" so that param[:search] = "ruby", nothing is returned and Solr isn't being called at all.

Started GET "/articles?utf8=%E2%9C%93&search=ruby" for 127.0.0.1 at 2013-01-17 12:37:58 -0800
  Processing by ArticlesController#index as HTML
  Parameters: {"utf8"=>"✓", "search"=>"ruby"}
  Article Load (0.5ms)  SELECT "articles".* FROM "articles"
Rendered articles/index.html.erb within layouts/application (11.5ms)
Completed 200 OK in 23ms (Views: 14.5ms | ActiveRecord: 0.5ms | Solr: 0.0ms)
[2013-01-17 12:37:58] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

Is there a problem with my conditional logic? Or, am I missing something about how Solr works? Thanks!

1
Why are you making this call: @articles = Article.all ?jdl
I want two instance variables available to Article#index ... @articles to show all articles and @search_results for the search results when user enters a search term. It's working fine except that @search_results is populated even when a search field is blank and params[:search] = ""Brett Sanders

1 Answers

1
votes

The Solr schema defines a defaultQuery to be run when no q param is supplied, or its value is an empty string.

Sunspot's defaultQuery is *:* (the match-all-docs query); furthermore, Sunspot itself more explicitly sends a *:* when fulltext is supplied with an empty string.

If you don't want a match-all-documents query in this case, you're best off checking the user-supplied query in your controller and skipping the call to Solr entirely.

This is actually exactly what you're doing in your example, so I'm perhaps unclear on the real question. You say, "The behavior I want is for nothing to be returned," and then, describing your conditional, "With this condition, nothing is returned." Seems like you've already solved your own problem?


Edit, on clarification:

Unless this is a typo, you probably want to change if params[:search] = "" to if params[:search] == "". Note the equality versus assignment operator.

(Or, better still: params[:search].blank?)