Moak
Moak

Reputation: 12885

How to sort elasticsearch by multiple fields while comparing the values of those fields to each other?

Let's say I have three objects

[
    {
        'name' : 'Apple',
        'popularityFoo': 100,
        'popularityBar': 80,
        'popularity': 40,
    },
    {
        'name' : 'Banana',
        'popularityFoo': 50,
        'popularityBar': 90,
        'popularity': 50,
    },
    {
        'name' : 'Cherry',
        'popularityFoo': 60,
        'popularityBar': 60,
        'popularity': 60,
    }  
];

My default sorting is by popularity, returning Cherry (60), Banana (50), Apple (40) If a user has a preferred category it will sort first by that category popularity index and then fall back to popularity. So if my favorite category is Foo it returns Apple (100), Cherry (60), Banana (50) and for category Bar the search returns Banana (90), Apple (80), Cherry (60)

Now my question: If my user likes both Foo and Bar how can I compare the different popularity values with each other when sorting so I can get the result Apple (100), Banana (90), Cherry (60)? Am I indexing wrong? Should I approach this differently?

I have 20 categories and my users have 1-3 favorite categories.

Upvotes: 1

Views: 3266

Answers (2)

Moak
Moak

Reputation: 12885

Thanks to Mohammad's answer for the hint, the way I solved this is using Math.max(double a, double b) nesting the function for each additional category.

"sort": [
    {
      "_script": {
        "script": "Math.max(doc['popularityFoo'].value, Math.max(doc['popularityBar'].value, doc['popularityBaz'].value))",
        "type": "number",
        "order": "desc"
      }
    }
]

Upvotes: 0

Mohammad Akbari
Mohammad Akbari

Reputation: 4776

Use script for conditional sorting as following:

{
    "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "lang": "painless",
                "inline": "doc['popularityFoo'].value > doc['popularityBar'].value ? doc['popularityFoo'].value : doc['popularityBar'].value"
            },
            "order" : "desc"
        }
    }
}

Upvotes: 1

Related Questions