Home > OS >  ElasticSearch sorting by more conditions
ElasticSearch sorting by more conditions

Time:01-09

I have index with simple data and I have to filter and sort it like this:

Records are like this:

{
"name": "Product ABC variant XYZ subvariant JKL",
"date": "2023-01-03T10:34:39 01:00"
}

And I'm searching name, where it is: "Product FGH"

  1. Get records with exact match (field name) and sort them by date (field date) DESC
  2. if nothing found in 1) or if there is not exact match, but similar records, then the rest records sort by default score.

Is it possible to do it in one elasticsearch request? And how it should look the whole query?

Thanks

CodePudding user response:

What you are looking for is running Elasticsearch queries based on the conditions, which is not possible in a single query, you need to first fire first query and if it doesn't return any hit, you need to fire the second one.

CodePudding user response:

Using script_query, you can do it how you want. Convert the date to milliseconds and assign it to the "_score" field for an exact match. for non exact match, you can simply return _score field

  1. For an exact match, it will be sorted by date field desc.
  2. For non exact match, it will sorted by _score field

For example:

Mapping:

{
  "mappings": {
    "properties": {
      "name" : {"type": "keyword"},
      "date" : {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}
    }
  }
}

Insert:

PUT func/_doc/1
{
  "name" : "Product ABC variant XYZ subvariant JKL",
  "date" : "2023-01-03 10:34:39"
}

PUT func/_doc/2
{
  "name" : "Product ABC variant XYZ subvariant JKL",
  "date" : "2022-12-03 10:33:39"
}

PUT func/_doc/3
{
  "name" : "Product ABC",
  "date" : "2022-11-03 10:33:39"
}

PUT func/_doc/4
{
  "name" : "Product ABC",
  "date" : "2023-01-03 10:33:39"
}

Query:

GET /func/_search
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
    },
      "script": {
        "source": "if (doc['name'].value == params.search_term) { doc['date'].value.toInstant().toEpochMilli(); } else return _score",
        "params": {
          "search_term": "Product ABC"
        }
      }
    }
  }
}

output:

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 1672742040000,
    "hits": [
      {
        "_index": "func",
        "_id": "4",
        "_score": 1672742040000,
        "_source": {
          "name": "Product ABC",
          "date": "2023-01-03 10:33:39"
        }
      },
      {
        "_index": "func",
        "_id": "3",
        "_score": 1667471640000,
        "_source": {
          "name": "Product ABC",
          "date": "2022-11-03 10:33:39"
        }
      },
      {
        "_index": "func",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "Product ABC variant XYZ subvariant JKL",
          "date": "2023-01-03 10:34:39"
        }
      },
      {
        "_index": "func",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "Product ABC variant XYZ subvariant JKL",
          "date": "2022-12-03 10:33:39"
        }
      }
    ]
  }
}
  • Related