Working with Blacklight Part 2 – displaying the result count

This is the second in of a series of posts about customizing Blacklight.

Last time, we implemented a feature that emailed a list of saved searches. We’d also like to display the number of results retrieved by each search. This task is a good way to learn about how a Solr response is stored and processed in Blacklight.

You can either start from a clean installation of Blacklight or build on the results of the previous exercise. A completed version is available on GitHub at https://github.com/ucsf-ckm/blacklight-email-tutorial.

Step 1: Add a “numresults” attribute to the Search model

Search history and saved searches are stored in an array of Search objects. The Search model in Blacklight holds the query_params for a search but doesn’t store the number of results. We’ll add an attribute, “numresults”, to store this value.

There are a few ways to do this in Rails – here, we’ll go with a migration.


rails g migration add_numresults_to_search numresults:integer

This should produce a new migration


class AddNumfoundToSearch < ActiveRecord::Migration
  def change
    add_column :searches, :numfound, :integer
  end
end

.. and run the migration


rake db:migrate

You may want to inspect the new schema or object to make sure that the model has been modified properly.

Step 1: Retrieve the number of results and store them in the Search object

Searches are created and stored in the search_context.rb class in the Blacklight gem (under lib/assets/blacklight/catalog/search_context.rb).


    saved_search ||= begin
      s = Search.create(:query_params => params_copy)
      add_to_search_history(s)
      s
    end

This code is not called explicitly in a controller – instead, it is run as a before_filter prior to the execution of any controller that includes it. This is mentioned in the comments at the top of the search_context.rb file.

This works for storing the query parameters, which are known before the controller is called. However, we won’t know the number of results in the Solr response until after the controller is called, so we’ll need to move this code the code for creating and saving a Search into a controller method.

We can get access to the object holding the solr response in the index method of the catalog controller (under lib/blacklight/catalog.rb in the Blacklight gem).


      (@response, @document_list) = get_search_results
      @filters = params[:f] || []

The get_search_results method in the solr_helper.rb runs a Solr query and returns a SolrResponse object (lib/solr_response.rb). Since this exercise is really about getting familiar with the Solr code base, it’s worth opening these classes and taking a look a how a query is executed and how results are stored.

The solr_response object (stored in @response, above) provides a hash with results data. The number of results is stored under “numFound”. We can now modify the index method to retrieve the number of results associated with a Solr query, add them to the Search object, and save the results.

Here’s the full code (add this to catalog_controller.rb in your local app).


 # get search results from the solr index
    def index

      (@response, @document_list) = get_search_results
      @filters = params[:f] || []

      params_copy = params.reject { |k,v| blacklisted_search_session_params.include?(k.to_sym) or v.blank? }

      return if params_copy.reject { |k,v| [:action, :controller].include? k.to_sym }.blank?

      saved_search = searches_from_history.select { |x| x.query_params == params_copy }.first

      s = Search.new(:query_params => params_copy)
      s.numfound = @response.response["numFound"]
      s.save
      add_to_search_history(s)

      respond_to do |format|
        format.html { }
        format.rss  { render :layout => false }
        format.atom { render :layout => false }

        format.json do
          render json: render_search_results_as_json
        end
      end
    end

Step 3: Add the number of results to the view

Now that the number of results is available in the Search object, you can easily display them in the index page in the saved_searches or search_history views.

Here’s the snippet for index.html.erb under saved_searches


<table class="table table-striped">
  <%- @searches.each do |search| -%>
    <tr>
      <td><%= link_to_previous_search(search.query_params) %></td>
      <td>results: <%= search.numfound %></td>
      <td><%= button_to t('blacklight.saved_searches.delete'), forget_search_path(search.id) %></td>
    </tr>
  <%- end -%>

The only change here is the addition of “search.numfound” populated in the controller method above.

You can add the number of results to the search_history similarly.

Step 4: Try it out

You should now be able to run a search, list the search history (or saved searches, depending on what views you modified), and view the number or results associated with each search.

One note – this numresults value won’t automatically update if new material is added to the index, but clicking on the search link would display the larger number of new files. So you could get out of sync here.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>