Master rank functions with Sunspot

How to sort using function queries + Solr dynamic fields in Sunspot

Posted on August 15, 2015

Solr dynamic fields are awesome for cases where we have schemaless documents. As I explained in a previous post, is easy to index, search and make a simple rank (sort) with dynamic fields in Sunspot.

However, for Solr-based applications is common to tune search ranks by defining function queries as the sort statement. In Sunspot, it's applied through order_by_function. However, how can we do that using dynamic fields ?

Sorting by function queries with dynamic fields

Using a dynamic field in function query (like sum or product) is not a trivial task, even when added directly to a Solr query:

 sort=sum(field(view:location_42),positions)+desc

In this example, view:location_42 is a dynamic field while positions is a static field. Dynamic field must be declared inside field clause, that's the secret. To manipulate a dynamic field in Sunspot, we have be in its scope:

dynamic :tech_skill do
  operations here (with, order, order_by_function, facet)
end

The problem here is that Sunspot query parser does not add field prefix to order operators. A possible workaround is to use adjust_solr_params statement. Then, we can change any query param before Sunspot submits the query to Solr. In our case, we set a function query in the sort param:

adjust_solr_params do |params|
  params[:sort] = "product(5, field(tech:ball_control_is))+desc"
end

Our dynamic field will receive a boost during the ranking. One drawback is that we have to provide the complete dynamic field name. That's why we have to provide is suffix. We do that because all fields are dynamic in Sunspot, so we are creating a dynamic field of a dynamic field, insane, right ?

That's it! I hope this short post brings great things. Keep on searching!