Multiple Custom Sorting in Elastic Search


(Luca) #1

Hello everyone,
I'm new in Elastic Search and before I getting started and learn it I would like to know if Elastic Search is what I need.

I already have a Solr DB server with an index of documents.
I need to show these documents to every user with their own particular orders.

Each document has a lot of properties, for example one document has a source ID, an array category ID (1 documents to more categories), a title and a date.

Every user can select multiple order to sort documents in home page: an user should ask documents first ordered by date, these documents order by source and then by category.

Every user can select the category and source priority: is not a simple natural sort ascending/descending.
For example an user select that the most important category for him/her is category with ID 101, the second important is category ID 18, the third is category ID 9570 etc...
Same goes for sources.

I'm able to order that documents in my PHP code (with custom sort functions and array_multisort() implementations) and in my JS part with a custom made sort function to List.js plugin and it works good if I load all documents needed for user request, but if I have to paginate results this does not work anymore.
I need to show hundreds/thousands documents to an user, for this reason I need to paginate results.
Because of pagination, documents returned from DB must be already sorted.

I write an example to explain better my question:
In my scenario an user can show this documents in a particular order, this order is decided by user in a settings view.

Order levels are for example:

  1. Order by category, as most important.
  2. Order by source, as second level.
  3. Order by date (ascending or descending).
  4. Order by title (ascending or descending).

For category order, in settings view, user has an box with a list of all categories available for him/her.
User drag&drop elements of the list to set in the favorite order.
Same goes for sources.

Let me show you an example of the list:
User show home page with a list of that documents:

documents : [
    0 => {
        "id" : 100,
        "title" : "Title A",
        "category" : [10, ...]
        "source" : 3,
        "date" : "2017-08-17",
        ...
    },
    1 => {
        "id" : 101,
        "title" : "Title B",
        "category" : [50, ...]
        "source" : 1,
        "date" : "2017-08-17",
        ...
    },
    2 => {
        "id" : 102,
        "title" : "Title A",
        "category" : [10, ...]
        "source" : 5,
        "date" : "2017-08-17",
        ...
    },
    3 => {
        "id" : 103,
        "title" : "Title C",
        "category" : [10, ...]
        "source" : 5,
        "date" : "2017-07-23",
        ...
    },
    4 => {
        "id" : 104,
        "title" : "Title C",
        "category" : [4, ...]
        "source" : 3,
        "date" : "2017-08-17",
        ...
    },
];

This user has the category order like:

category_order: [
    0 => 10,
    1 => 4,
    2 => 50,
]

... and source order is like:

source_order: [
    0 => 5,
    1 => 3,
    2 => 1000,
    3 => 1
]

Now, this user has specified in settings that he/she will show:

  1. first documents order by category
  2. then, user will have these documents in source order
  3. then, order by date DESCENDING (newest first)
  4. and finally by name as last order ASCENDING (A to Z).

I have to query documents from Solr with these orders.
The results would be like
1st) document with id = 102,
2nd) document with id = 103,
3rd) document with id = 100,
4th) document with id = 104,
5th) document with id = 101,

I hope I explained it well.

PS: If you need to show the custom sort function that sort elements of a list (instance object of jQuery plugin List.js) in the correct order asked by user let me know, I will post it on Pastebin.

I need to know if there is a way to do it with Elastic Search.

Thank you

Luca


(Abdon Pijpelink) #2

Yes, this is perfectly possible with Elasticsearch. With each search request you send to Elasticsearch you can provide the desired sort order for the results to be returned in: https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-request-sort.html

You can provide multiple sort clauses to indicate what the primary, secondary, etc sort order should be. And because the sort clause can be different for each search request you send to Elasticsearch, you can give each user their own sort order.


(Luca) #3

Hello,
thank you very much for your response.
Is not quite what I would like to do: the order that I will give to category and sources is not a natural sort: it's a custom sort.

In mySQL db it is called order by FIELD
An example is: ORDER BY FIELD(Language,'ENU','JPN','DAN'), ID
With this example I'm getting results first content with filed Language == ENU, then Language == JPN then Language == DAN and then order by ID.


(Abdon Pijpelink) #4

It sounds like script-based sorting could offer what you're looking for:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_script_based_sorting


(system) #5

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.