Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add score to elasticsearch completion suggester inputs

I need to implement elasticsearch completion suggester.

I have an index mapped like this:

{
  "user": {
    "properties": {
      "username": {
        "index": "not_analyzed",
        "analyzer": "simple",
        "type": "string"
      },
      "email": {
        "index": "not_analyzed",
        "analyzer": "simple",
        "type": "string"
      },
      "name": {
        "index": "not_analyzed",
        "analyzer": "simple",
        "type": "string"
      },
      "name_suggest": {
        "payloads": true,
        "type": "completion"
      }
    }
  }
}

I add documents to the index like this:

{
  "doc": {
    "id": 1,
    "username": "jack",
    "name": "Jack Nicholson",
    "email": "[email protected]",
    "name_suggest": {
      "input": [
        "jack",
        "Jack Nicholson",
        "[email protected]"
      ],
      "payload": {
        "id": 1,
        "name": "Jack Nicholson",
        "username": "jack",
        "email": "[email protected]"
      },
      "output": "Jack Nicholson (jack) - [email protected]"
    }
  },
  "doc_as_upsert": true
}

And I send this request to my_index/_suggest:

{
  "user": {
    "text": "jack",
    "completion": {
      "field": "name_suggest"
    }
  }
}

I get the resulting options that look like this:

[
  {
    "text": "John Smith",
    "score": 1.0,
    "payload": {
      "id": 11,
      "name": "John Smith",
      "username": "jack",
      "email": "[email protected]"
    }
  },
  {
    "text": "Jack Nickolson",
    "score": 1.0,
    "payload": {
      "id": 1,
      "name": "Jack Nickolson",
      "username": "jack.n",
      "email": "[email protected]"
    }
  },
  {
    "text": "Jackson Jermaine",
    "score": 1.0,
    "payload": {
      "id": 10,
      "name": "Jackson Jermaine",
      "username": "jermaine",
      "email": "[email protected]"
    }
  },
  {
    "text": "Tito Jackson",
    "score": 1.0,
    "payload": {
      "id": 9,
      "name": "Tito Jackson",
      "username": "tito",
      "email": "[email protected]"
    }
  },
  {
    "text": "Michael Jackson",
    "score": 1.0,
    "payload": {
      "id": 6,
      "name": "Michael Jackson",
      "username": "michael_jackson",
      "email": "[email protected]"
    }
  }
]

This works fine but, I need to have the options sorted that way that those that have username matched come first. I can do it manually, but that would prevent me to use length and offset and would be slower.

Is it possible to add scoring to the individual inputs (not the whole suggests), and that way affect the sorting? With the approach that I use it seems it is not.

Another related question, is it possible to specify in the input an array of fields instead of an array of values, and that way avoid the duplication? If yes, would setting the score on the fields be taken into account when ES generates suggestions?

like image 652
bosskovic Avatar asked Mar 17 '14 16:03

bosskovic


1 Answers

You can add score to your input with the weight option.

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html#indexing

like image 84
Max Avatar answered Oct 02 '22 16:10

Max