script_score介绍
在Elasticsearch中,script_score是在function_score查询中的一种功能强大的方式,允许用户使用内置Painless脚本语言或者其他支持的语言来动态计算每个文档的评分
script_score语法
bash
GET /<索引名>/_search
{
"query": {
"function_score": {
"query": { "match_all": {} }, // 或者其它查询条件
"functions": [
{
"script_score": {
"script": {
"source": """
double customScore = 0;
if (doc['field1'].value > params.threshold1) {
customScore += doc['field1'].value * params.multiplier1;
}
customScore += doc['field2'].value;
return customScore;
""",
"params": {
"threshold1": 50,
"multiplier1": 0.5
}
}
}
}
],
"score_mode": "sum", // 或者其它score_mode
"boost_mode": "replace" // 或者其它boost_mode
}
}
}
- script_score被用来定义一个脚本,该脚本计算文档的自定义评分
- source字段内是Painless脚本,它可以访问文档中的字段值(如doc['field1'].value和doc['field2'].value)并对它们进行计算
- params是一个键值对对象,用于传递给脚本的参数,此处定义了两个参数:threshold1和multiplier1
script_score 案例
场景
假设我们有一个问答论坛索引,需要基于回答数量和点赞数查找高质量
索引创建
bash
PUT /forum_questions
{
"mappings": {
"properties": {
"question": {
"type": "text"
},
"answer_count": {
"type": "long"
},
"upvotes": {
"type": "long"
}
}
}
}
文档插入
bash
POST /forum_questions/_doc/
{
"question": "What is Elasticsearch?",
"answer_count": 5,
"upvotes": 20
}
POST /forum_questions/_doc/
{
"question": "How to configure Elasticsearch for production?",
"answer_count": 3,
"upvotes": 15
}
POST /forum_questions/_doc/
{
"question": "Best practices for indexing data in Elasticsearch?",
"answer_count": 10,
"upvotes": 30
}
POST /forum_questions/_doc/
{
"question": "How to optimize Elasticsearch performance?",
"answer_count": 8,
"upvotes": 18
}
POST /forum_questions/_doc/
{
"question": "What are shards and replicas in Elasticsearch?",
"answer_count": 6,
"upvotes": 25
}
POST /forum_questions/_doc/
{
"question": "How to handle time-based data in Elasticsearch?",
"answer_count": 4,
"upvotes": 12
}
POST /forum_questions/_doc/
{
"question": "What is the difference between match and term queries?",
"answer_count": 7,
"upvotes": 23
}
POST /forum_questions/_doc/
{
"question": "How to set up Elasticsearch clusters?",
"answer_count": 9,
"upvotes": 16
}
查询
bash
GET /forum_questions/_search
{
"query": {
"function_score": {
"query": { "match_all": {} }, // 或者使用具体查询条件
"functions": [
{
"script_score": {
"script": {
"source": """
double score = 0;
score += doc['answer_count'].value * params.answer_weight;
score += doc['upvotes'].value * params.upvote_weight;
return score;
""",
"params": {
"answer_weight": 0.7,
"upvote_weight": 0.3
}
}
}
}
],
"score_mode": "sum"
}
}
}