Elastic multi-level order search

I would like to be able to return typeahead elements in a specific order. For example, a search Parashould return:

 Paracetamol

 Parafin

 LIQUID PARAFFIN

 ISOMETHEPTENE WITH PARACETAMOL

1) Sentences starting with para should be sorted above and in alphabetical order

2) The remaining elements should appear below, as well as in alphabetical order

Is this possible with Elasticsearch?

Update

What if I wanted the result to be like this:

 Paracetamol

 Parafin

 Amber Paraffin

 ISOMETHEPTENE WITH PARACETAMOL

 LIQUID PARAFFIN

Thus, all terms containing the prefix are at the top and everything else is in alphabetical order.

+3
source share
1 answer

This is my suggestion (also need to include scripts):

PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "standard",
            "lowercase",
            "ngram"
          ]
        },
        "search_ngram": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": "lowercase"
        }
      },
      "filter": {
        "ngram": {
          "type": "ngram",
          "min_gram": 2,
          "max_gram": 15
        }
      }
    }
  },
  "mappings": {
    "test": {
      "properties": {
        "text": {
          "type": "string",
          "index_analyzer": "autocomplete",
          "search_analyzer": "search_ngram",
          "index_options": "positions",
          "fields": {
            "not_analyzed_sorting": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}

POST test/test/_bulk
{"index":{"_id":1}}
{"text":"Paracetamol"}
{"index":{"_id":2}}
{"text":"Paracetamol xxx yyy zzz"}
{"index":{"_id":3}}
{"text":"Parafin"}
{"index":{"_id":4}}
{"text":"LIQUID PARAFFIN"}
{"index":{"_id":5}}
{"text":"ISOMETHEPTENE WITH PARACETAMOL"}

GET /test/test/_search
{
  "query": {
    "match": {
      "text": "Para"
    }
  },
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": "termInfo=_index[field_to_search].get(term_to_search.toLowerCase(),_POSITIONS);if (termInfo) {for(pos in termInfo){return pos.position}};return 0;",
        "params": {
          "term_to_search": "Para",
          "field_to_search": "text"
        },
        "order": "asc"
      }
    },
    {
      "text.not_analyzed_sorting": {
        "order": "asc"
      }
    }
  ]
}

UPDATE

, , :

{
  "query": {
    "match": {
      "text": "Para"
    }
  },
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": "termInfo=_index[field_to_search].get(term_to_search.toLowerCase(),_POSITIONS);if (termInfo) {for(pos in termInfo){if (pos.position==0) return pos.position; else return java.lang.Integer.MAX_VALUE}};return java.lang.Integer.MAX_VALUE;",
        "params": {
          "term_to_search": "Para",
          "field_to_search": "text"
        },
        "order": "asc"
      }
    },
    {
      "text.not_analyzed_sorting": {
        "order": "asc"
      }
    }
  ]
}
+3

Source: https://habr.com/ru/post/1613909/


All Articles