I am using solr and have come across an interesting sorting request that I have not been able to overcome.
The request is that for a single search phrase against a single indexed field, the results are sorted by the items that 'start with' the search phrase first, then the remainder of the results are sorted alphabetically.
For example, given the solr index containing ['reversion catapult', 'rat', 'catering', 'mat', 'cat', 'volkswagen', 'recatogorize', 'a total catastrophe']
, the search phrase 'cat' should return the results in the following order:
cat, catering, a total catastrophe, recatogorize, reversion catapult
Using query boosting, I have been able to get the first part of the requirement where the 'starts with' matches are at the top of the list, but I cannot get the remainder of the items to sort alphabetically.
Here is my current q statement (using solrJ):
((entity_name_search:" + "\"" + URLEncoder.encode(descSearchString, CharacterEncoding.UTF_8)
+ "*^2\") OR (entity_name_search:"
+ "\"" + URLEncoder.encode(descSearchString, CharacterEncoding.UTF_8) + "\"))
Any help would be appreciated.
Using a brute force approach, the results of the query sorting the field alphabetically (as noted in Binoy's Post) against the index are returned and iterated over. Two JSON Objects are created, one which contains all of the results that 'start with' the search term, the second one for all the others. The results look something like this:
JSONArray priorityOneJSON = new JSONArray();
JSONArray priorityTwoJSON = new JSONArray();
for (int i = 0; i < completeJSON.length(); i++) {
JSONObject jobj = completeJSON.getJSONObject(i);
String name = jobj.getString(parameters.get(FIELD_TO_SORT_KEY));
if (name.toUpperCase().startsWith(parameters.get(FIELD_KEY))) {
priorityOneJSON.put(jobj);
} else {
priorityTwoJSON.put(jobj);
}
}
JSONArray result = new JSONArray();
for (int i = 0; i < priorityOneJSON.length(); i++) {
result.put(priorityOneJSON.get(i));
}
for (int i = 0; i < priorityTwoJSON.length(); i++) {
result.put(priorityTwoJSON.get(i));
}
tempJSON.put(parameters.get(OBJ_TO_SORT_KEY), result);
jsonObject.put(parameters.get(MAIN_OBJ_KEY), tempJSON);
LOGGER.log(Level.FINE, "Final JSON: " + jsonObject);
return jsonObject;
In the code above, completeJSON
is the JSON results of the SOLR query. We iterate over that array and pull out the field that we care about. We then perform the 'startsWith' operation to determine if this result should be in the first sort set or the second, and place it accordingly.
We then take the two arrays and basically jam them into another array. This entire solution seems way to process intensive, but was the best that could be done on the very short timeframe that we had.