5

I'm not very experienced with ElasticSearch and would like to know how to boost a search based on a certain integer value.

This is an example of a document:

{
    "_index": "links",
    "_type": "db1",
    "_id": "mV32vWcBZsblNn1WqTcN",
    "_score": 8.115617,
    "_source": {
        "url": "example.com",
        "title": "Example website",
        "description": "This is an example website, used for various of examples around the world",
        "likes": 9,
        "popularity": 543,
        "tags": [
            {
                "name": "example",
                "votes": 5
            },
            {
                "name": "test",
                "votes": 2
            },
            {
                "name": "testing",
                "votes": 1
            }
        ]
    }
}

Now in this particular search, the focus is on the tags and I would like to know how to boost the _score and multiply it by the integer in the votes under tags.

If this is not possible (or very hard to achieve), I would simply like to know how to boost the _score by the votes (not under tags)

Example, add 0.1 to the _score for each integer in votes

This is the current search query I'm using (for searching tags only):

{
    "query": {
        "nested": {
            "path": "tags",
            "query": {
                "bool":{
                    "should":{
                        "match":{
                            "tags.name":"example,testing,something else"
                        }
                    }
                }
            }
        }
    }
}

I couldn't find much online, and hope someone can help me out.

How do I boost the _score with an integer value?


Update

For more info, here is the mapping:

{
    "links": {
        "mappings": {
            "db1": {
                "properties": {
                    "url": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "title": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "description": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "likes": {
                        "type": "long"
                    },
                    "popularity": {
                        "type": "long"
                    },
                    "tags": {
                        "type": "nested",
                        "properties": {
                            "name": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            },
                            "votes": {
                                "type": "long"
                            }
                        }
                    }
                }
            }
        }
    }
}

Update 2

Changed the tags.likes/tags.dislikes to tags.votes, and added a nested property to the tags

6
  • Can you show your mapping? Is tags of nested type? Commented Dec 23, 2018 at 7:49
  • @Val I updated the question, and added the mapping. I don't know if this is nested or not. Commented Dec 23, 2018 at 16:35
  • Thanks, the issue is then that tags should be nested if you want to achieve what you expect, otherwise you cannot query specific nested tags in order to get their likes/dislikes values to boost the score. Commented Dec 23, 2018 at 16:37
  • @Val I would expect something like that. But by nesting the tags, does it mean that I can't set custom/new "names"? Would the mapping need to be HUGE to cover all the tags in the world? Or would I just need to change the mapping a bit? I'm considering making a db2, and slowly migrate all the documents to a new mapping structure Commented Dec 23, 2018 at 16:42
  • See this: elastic.co/guide/en/elasticsearch/reference/current/nested.html Commented Dec 23, 2018 at 16:43

2 Answers 2

4

This took a long time to figure out. I have learnt so much on my way there.

Here is the final result:

{
    "query": {
        "nested": {
            "path": "tags",
            "query": {
                "function_score": {
                    "query": {
                        "bool": {
                            "should": [
                                {
                                    "match": {
                                        "tags.name": "example"
                                    }
                                },
                                {
                                    "match": {
                                        "tags.name": "testing"
                                    }
                                },
                                {
                                    "match": {
                                        "tags.name": "test"
                                    }
                                }
                            ]
                        }
                    },
                    "functions": [
                        {
                            "field_value_factor": {
                                "field": "tags.votes"
                            }
                        }
                    ],
                    "boost_mode": "multiply"
                }
            }
        }
    }
}

The array in should has helped a lot, and was glad I could combine it with function_score

Sign up to request clarification or add additional context in comments.

Comments

2

You are looking at function score query: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html

And field value factor https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-field-value-factor.

Snippet from documentation:

GET /_search
{
    "query": {
        "function_score": {
            "field_value_factor": {
                "field": "tags.dislikes",
                "factor": 1.2,
                "modifier": "sqrt",
                "missing": 1
            }
        }
    }
}

Or with script score because your nested tags field (not sure if field value score works fine with nested structure).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.