Elasticsearch - filter and sort by name with Priority exceptions Elasticsearch - filter and sort by name with Priority exceptions elasticsearch elasticsearch

Elasticsearch - filter and sort by name with Priority exceptions


If using Elasticsearch version 1.x, following query should provide you with the expected result:(might have to adapt a bit to use raw fields if needed)

{  "from": 0,  "size": 500,  "query": {    "filtered": {      "query": {        "bool": {          "should": [            {              "term": {                "brand.names.1": "ccc",                "boost": 10              }            },            {              "exists": {                "field": "brand.id"              }            }          ]        }      },      "filter": {        "exists": {          "field": "brand.id"        }      }    }  },  "sort": [    "_score",    {      "brand.names.1": {        "order": "asc"      }    }  ]}

On later versions of Elasticsearch The filtered query is replaced by the bool query,this query should do the job (with similar adaptation as previous one for use of raw fields if needed)

{  "from": 0,  "size": 500,  "query": {    "bool": {      "filter": {        "exists": {          "field": "brand.id"        }      },      "should": [        {          "term": {            "brand.names.1": "ccc"          }        }      ]    }  },  "sort": [    "_score",    {      "brand.names.1": {        "order": "asc"      }    }  ]}

In both cases, you can make use of the boost function if you want to have the top filled with more than one preferred match, in a given order


I have tested localy here it is. Also to simplify query ask NOT for name but for brand IDS since your brand could have many names. If you still wish to do sort on names then you can modify script as you wish

POST stack/_search{  "query": {    "function_score": {      "boost_mode": "replace",      "query": {        "bool": {          "must": [            {              "exists": {                "field": "brand.id"              }            }          ]        }      },      "script_score": {        "script": {          "params": {            "ids": [              406,              405            ]          },          "inline": "return params.ids.indexOf(doc['brand.id'].value) > -1 ? 1000 - params.ids.indexOf(doc['brand.id'].value) : _score;"        }      }    }  }}


If the priority of brand is known at index time, then you can directly index it in your doc like :

"brand": {      "name": "ccc",      "priority":1000,      "id": 407    }

The brands to be shown on top can have a high popularity value, whereas the rest can have a popularity value assigned to a lower value.

By indexing it this way, you can directly sort it by using brand.popularity as the primary sort and brand.names as the secondary sort

"sort" : [        { "brand.priority" : {"order" : "desc"}},        { "brand.name" : {"order" : "asc" }}    ]