ElasticSearch - function_score (weight具体实例)

阅读本文需要先了解function_score的相关知识,请看 ElasticSearch - function_score 简介


  • 先准备数据和索引,在ES插入三笔数据,其中language是keywork类型,like是integer类型(代表点赞量)

    { "language": "java", "like": 5 }
    { "language": "python", "like": 5 }
    { "language": "go", "like": 10 }
  • functions是一个数组,裡面放著的是将要被使用的加强函数列表,我们在裡面使用了3个filter去过滤数据,并且每个filter都设置了一个加强函数,并且还使用了一个会应用到所有文档的field_value_factor加强函数

    • 可以为列表裡的每个加强函数都指定一个filter,这样做的话,只有在文档满足此filter的要求,此filter的加强函数才会应用到文挡上,也可以不指定filter,这样的话此加强函数就会应用到全部的文挡上

    • 一个文档可以一次满足多条加强函数和多个filter,如果一次满足多个,那麽就会产生多个加强score

    • 因此ES会先使用score_mode定义的方式来合併这些加强score们,得到一个总加强score,得到总加强score之后,才会再使用boost_mode定义的方式去和old_score做合併

    GET 127.0.0.1/mytest/doc/_search
    {
        "query": {
            "function_score": {
                "query": {
                    "match_all": {}  //match_all查出来的所有文档的_score都是1
                },
                "functions": [
                    //第一个filter(使用weight加强函数),如果language是java,加强score就是2
                    {
                        "filter": {
                            "term": {
                                "language": "java"
                            }
                        },
                        "weight": 2
                    },
                    //第二个filter(使用weight加强函数),如果language是go,加强score就是3
                    {
                        "filter": {
                            "term": {
                                "language": "go"
                            }
                        },
                        "weight": 3
                    },
                    //第三个filter(使用weight加强函数),如果like数大于等于10,加强score就是5
                    {
                        "filter": {
                            "range": {
                                "like": {
                                    "gte": 10
                                }
                            }
                        },
                        "weight": 5
                    },
                    //field_value_factor加强函数,会应用到所有文档上,加强score就是like值
                    {
                        "field_value_factor": {
                            "field": "like"
                        }
                    }
                ],
                "score_mode": "multiply", //设置functions裡面的加强score们怎麽合併成一个总加强score
                "boost_mode": "multiply" //设置old_score怎麽和总加强score合併
            }
        }
    }
    "hits": [
        {
            "_score": 150, //go同时满足filter2、filter3,且还有一个加强函数field_value_factor产生的加强,因此加强score为3, 5, 10,总加强score为3*5*10=150
            "_source": { "language": "go", "like": 10 }
        },
        {
            "_score": 10, //java只满足filter1,但是因为还有field_value_facotr产生的加强score,因此加强score为2, 5,总加强score为2*5=10
            "_source": { "language": "java", "like": 5 }
        },
        {
            "_score": 5, //python不满足任何filter,因此加强score只有field_value_factor的like值,就是5
            "_source": { "language": "python", "like": 5 }
        }
    ]
  • 其实weight加强函数也是可以不和filter搭配,自己单独使用的,只是这样做没啥意义,因为只是会给全部的文档都增加一个固定值而已

    • 不过就DSL语法上来说,他也像其他加强函数一样,是可以直接使用而不用加filter的

    GET 127.0.0.1/mytest/doc/_search
    {
        "query": {
            "function_score": {
                "query": {
                    "match_all": {}
                }
            },
            functions: [
                {
                    "weight": 3
                }
            ]
        }
    }
    "hits": [
        {
            "_score": 3,
            "_source": { "language": "go", "like": 10 }
        },
        {
            "_score": 3,
            "_source": { "language": "python", "like": 5 }
        },
        {
            "_score": 3,
            "_source": { "language": "java", "like": 5 }
        }
    ]
  • weight加强函数也可以用来调整每个语句的贡献度,权重weight的默认值是1.0,当设置了weight,这个weight值会先和自己那个{}裡的每个句子的评分相乘,之后再通过score_mode和其他加强函数合併

    • 下面的查询,公式为new_score = old_score * [ (like值 * weight1) + weight2 ]

    • 公式解析 : weight1先加强like值(只能使用乘法),接著再透过score_mode定义的方法(sum)和另一个加强函数weight2合併,得到一个总加强score,最后再使用boost_mode定义的方法(默认是multiply)和old_score做合併,得到new_score

    GET 127.0.0.1/mytest/doc/_search
    {
        "query": {
            "function_score": {
                "query": {
                    "match_all": {}
                }
            },
            functions: [
                {
                    "field_value_factor": {
                        "field": "like"
                    },
                    "weight": 3  //weight1, 加强field_value_factor,只能使用乘法,无法改变
                },
                {
                    "weight": 20 //weight2
                }
            ],
            "score_mode": "sum"
        }
    }
    "hits": [
        {
            "_score": 50,
            "_source": { "language": "go", "like": 10 }
        },
        {
            "_score": 35,
            "_source": { "language": "python", "like": 5 }
        },
        {
            "_score": 35,
            "_source": { "language": "java", "like": 5 }
        }
    ]

猜你喜欢

转载自blog.csdn.net/weixin_40341116/article/details/80931573