Elasticsearch layered ordering

前端 未结 1 1422
逝去的感伤
逝去的感伤 2020-12-19 18:33

I would like to be able to return typeahead items in a certain order. For example, search for Para should return:

 Paracetamol

 Parafin

 LIQUI         


        
1条回答
  •  遥遥无期
    2020-12-19 18:43

    This is my suggestion (also, you need to enable scripting):

    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

    For your updated question, even if I would have preferred to have another post, use the following query:

    {
      "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"
          }
        }
      ]
    }
    

    0 讨论(0)
提交回复
热议问题