Sonu
Sonu

Reputation: 179

Sort the search result in ascending order of a multivalued field in Solr

I'm using Solr of version 6.6.0. I have a schema of title (text_general), description(text_general), id(integer). When I search for a keyword to list the results in ascending order of the title my code returns an error can not sort on multivalued field: title.

I have tried to set the sort using the following 3 methods

SolrQuery query = new SolrQuery();
1. query.setSort("title", SolrQuery.ORDER order);
2. query.addSort("title", SolrQuery.ORDER order);
3. SortClause ab = new SolrQuery.SortClause("title", SolrQuery.ORDER.asc);
   query.addSort(ab);

but all of these returns the same error

I found a solution by referring to this answer

It says to use min/max functions. query.setSort(field("pageTitle",min), ORDER.asc); this what I'm trying to set as the query, I didn't understand what are the arguments used here.

This is the maven dependency that I'm using

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>6.5.1</version>
</dependency>

Upvotes: 2

Views: 3112

Answers (2)

EricLavault
EricLavault

Reputation: 16065

The first thing to check is do you really need that title field to be multivalued, or do your documents really have multiple titles ? If not, you just need to fix the field definition by setting multivalued="false".

That said, sorting on a multivalued field doesn't make sense unless determining which one of these multiple values should be used to sort on, or how to combine them into one.

Let' say we need to sort a given resultset by title (alphabetically), first using a single-valued title field :

# Unsorted
"docs": [
  { "id": "1", "title": "One" },
  { "id": "2", "title": "Two" },
  { "id": "3", "title": "Three" },
]

# Sorted
"docs": [
  { "id": "1", "title": "One" },
  { "id": "3", "title": "Three" },
  { "id": "2", "title": "Two" },
]

# -> ok no problem here

Now applying the same logic with a multi-valued field is not possible as is, you would necessarily need to determine which title to use in each document to properly sort them :

# Unorted
"docs": [
  { "id": "1", "title": ["One", "z-One", "a-One"] },
  { "id": "2", "title": ["Two", "z-Two", "a-Two"] },
  { "id": "3", "title": ["Three", "z-Three", "a-Three"] }
]

Fortunately, Solr allows to sort results by the output of a function, meaning you can use any from Solr's function queries to "get" a single value per title field. The answer you referred to is a good example even though it may not work for you (because title would need docValues enabled - depends on field definition - and knowing that max/min functions should be used only with numeric values), just to get the idea :

# here the 2nd argument is a callback to max(), used precisely to get a single value from title
sort=field(title,max) asc

Upvotes: 1

MatsLindh
MatsLindh

Reputation: 52832

Unless title actually is multiValued - can your post have multiple titles - you should define it as multiValued="false" in your schema. However, there's a second issue - a field of the default type text_general isn't suited for sorting, as it'll generate multiple tokens, one for each word in the title. This is useful for searching, but will give weird and non-intuitive results when sorting.

So instead, define a title_sort field and use a field type with a KeywordTokenizer and LowerCaseFilter attached (if you want case insensitive sort), or if you want case sensitive sort, use the already defined string field type for the title_sort field.

Upvotes: 3

Related Questions