Tuning ranking in search result

Viewed 42
doc1 = {"id":1,"text":"tonight"}
doc2 = {"id":2,"text":"tonight tonight"}
doc3 = {"id":3,"text":"tonight tonight tonight"}
doc4 = {"id":4,"text":"tonight and something else"}
doc5 = {"id":5,"text":"tonight and you"}

es.index(index="tonight", document=doc1)
es.index(index="tonight", document=doc2)
es.index(index="tonight", document=doc3)
es.index(index="tonight", document=doc4)
es.index(index="tonight", document=doc5)

Suppose I have the above documents indexed. When I use the below query:

data = json.dumps({
    "query":{ 
        "bool":{
            "should":[
                {
                    "match":{
                        "text": "tonight"
                    }
                }
            ]
        }
    }
})

The hits returned in the order of "tonight tonight tonight", "tonight tonight","tonight", "tonight and you" and "tonight and something else".

May I ask if there is a way to make "tonight" as the first hit returned with highest _score?

In my real life use case, I am conducting iterating throught the whole index to find out the most relevant text other than itself, and the document being searched should be returned as the first hit (most matched) if possible.

Could someone please give me some ideas on how to query?

Thank you!!!

1 Answers

If you are using Elasticsearch default index mapping, then you can use a term query on the text.keyword field. Otherwise, you can add multi fields to the text field using Update Mapping API.

The term query is used to return documents that match exactly with the search term.

You can include the term query in the bool should clause, which will increase the score of exact matching documents, as compared to the other documents' score.

{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "text": "tonight"
                    }
                },
                {
                    "term": {
                        "text.keyword": "tonight"
                    }
                }
            ]
        }
    }
}

Search Results will be

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 5,
            "relation": "eq"
        },
        "max_score": 1.5025805,
        "hits": [
            {
                "_index": "stof",
                "_id": "1",
                "_score": 1.5025805,
                "_source": {
                    "id": 1,
                    "text": "tonight"
                }
            },
            {
                "_index": "stof",
                "_id": "3",
                "_score": 0.13236837,
                "_source": {
                    "id": 3,
                    "text": "tonight tonight tonight"
                }
            },
            {
                "_index": "stof",
                "_id": "2",
                "_score": 0.12794474,
                "_source": {
                    "id": 2,
                    "text": "tonight tonight"
                }
            },
            {
                "_index": "stof",
                "_id": "5",
                "_score": 0.08185939,
                "_source": {
                    "id": 5,
                    "text": "tonight and you"
                }
            },
            {
                "_index": "stof",
                "_id": "4",
                "_score": 0.07130444,
                "_source": {
                    "id": 4,
                    "text": "tonight and something else"
                }
            }
        ]
    }
}
Related