首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >painless语法入门[通俗易懂]

painless语法入门[通俗易懂]

作者头像
全栈程序员站长
发布2022-08-01 15:16:21
发布2022-08-01 15:16:21
1.6K0
举报

大家好,又见面了,我是你们的朋友全栈君。

painless语法

painless基础结构

代码语言:javascript
复制
  "script": { 
   
    "lang":   "...",
    "source" | "id": "...",
    "params": { 
    ... }
  }
  1. lang: 定义脚本使用的语言, 默认painless
  2. source, id: 脚本的主体, source后面跟着内联的脚本代码, id后面跟着脚本的id, 具体代码存在于脚本id对应的代码中
  3. params: 定义一些变量的值, 使用params可以减少脚本的编译次数. 因为如果变量的值硬编码到代码中, 每次进行变量值得更改都会对脚本进行重新编译. 使用params则不会重新编译脚本.

script.context.field.max_compilations_rate=75/5m 脚本的默认编译频率, 定义脚本的编译频率为5分钟75个, 当超过75个时会抛出circuit_breaking_exception异常.

脚本代码的存储

代码语言:javascript
复制
// POST _scripts/{id}
POST _scripts/calculate-score
{ 
   
  "script": { 
   
    "lang": "painless",
    "source": "Math.log(_score * 2) + params['my_modifier']"
  }
}

// 脚本使用
GET my-index-000001/_search
{ 
   
  "query": { 
   
    "script_score": { 
   
      "query": { 
   
        "match": { 
   
            "message": "some message"
        }
      },
      "script": { 
   
        "id": "calculate-score", 
        "params": { 
   
          "my_modifier": 2
        }
      }
    }
  }
}

使用脚本对文档进行更新

代码语言:javascript
复制
PUT my-index-000001/_doc/1
{ 
   
  "counter" : 1,
  "tags" : ["red"]
}

// 将count加上4
POST my-index-000001/_update/1
{ 
   
  "script" : { 
   
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params" : { 
   
      "count" : 4
    }
  }
}

// 增加tags的元素
POST my-index-000001/_update/1
{ 
   
  "script": { 
   
    "source": "ctx._source.tags.add(params['tag'])",
    "lang": "painless",
    "params": { 
   
      "tag": "blue"
    }
  }
}

// If the list contains duplicates of the tag, this script just removes one occurrence.
// 如果集合中有多个相同的值, 只删除第一个
POST my-index-000001/_update/1
{ 
   
  "script": { 
   
    "source": "if (ctx._source.tags.contains(params['tag'])) { ctx._source.tags.remove(ctx._source.tags.indexOf(params['tag'])) }",
    "lang": "painless",
    "params": { 
   
      "tag": "blue"
    }
  }
}

// 增加新的字段
POST my-index-000001/_update/1
{ 
   
  "script" : "ctx._source.new_field = 'value_of_new_field'"
}

// 删除字段
POST my-index-000001/_update/1
{ 
   
  "script" : "ctx._source.remove('new_field')"
}

// 如果tags字段中包含green, 则删除该文档, 否则不做操作
POST my-index-000001/_update/1
{ 
   
  "script": { 
   
    "source": "if (ctx._source.tags.contains(params['tag'])) { ctx.op = 'delete' } else { ctx.op = 'none' }",
    "lang": "painless",
    "params": { 
   
      "tag": "green"
    }
  }
}

// doc.containsKey('field')

脚本变量

  • ctx._source.field: add, contains, remove, indexOf, length
  • ctx.op: The operation that should be applied to the document: index or delete
  • ctx._index: Access to document metadata fields
  • _score 只在script_score中有效
  • doc[‘field’], doc[‘field’].value: add, contains, remove, indexOf, length

脚本缓存

  1. You can change this behavior by using the script.cache.expire setting. Use the script.cache.max_size setting to configure the size of the cache.The size of scripts is limited to 65,535 bytes. Set the value of script.max_size_in_bytes to increase that soft limit.
  2. Cache sizing is important. Your script cache should be large enough to hold all of the scripts that users need to be accessed concurrently.

脚本优化

  1. 使用脚本缓存, 预先缓存可以节省第一次的查询时间
  2. 使用ingest pipeline进行预先计算
  3. 相比于_source.field_name使用doc[‘field_name’]语法速度更快, doc语法使用doc value , 列存储
代码语言:javascript
复制
// 根据分数相加结果进行排序
GET /my_test_scores/_search
{ 
   
  "query": { 
   
    "term": { 
   
      "grad_year": "2099"
    }
  },
  "sort": [
    { 
   
      "_script": { 
   
        "type": "number",
        "script": { 
   
          "source": "doc['math_score'].value + doc['verbal_score'].value"
        },
        "order": "desc"
      }
    }
  ]
}

// 在索引中新加一个字段存储计算结果
PUT /my_test_scores/_mapping
{ 
   
  "properties": { 
   
    "total_score": { 
   
      "type": "long"
    }
  }
}

// 使用ingest pipeline先将计算结果作为值存储起来
PUT _ingest/pipeline/my_test_scores_pipeline
{ 
   
  "description": "Calculates the total test score",
  "processors": [
    { 
   
      "script": { 
   
        "source": "ctx.total_score = (ctx.math_score + ctx.verbal_score)"
      }
    }
  ]
}

// 重新索引时使用ingest pipeline
POST /_reindex
{ 
   
  "source": { 
   
    "index": "my_test_scores"
  },
  "dest": { 
   
    "index": "my_test_scores_2",
    "pipeline": "my_test_scores_pipeline"
  }
}

// 索引新文档时使用ingest pipeline
POST /my_test_scores_2/_doc/?pipeline=my_test_scores_pipeline
{ 
   
  "student": "kimchy",
  "grad_year": "2099",
  "math_score": 1200,
  "verbal_score": 800
}

// 查询
GET /my_test_scores_2/_search
{ 
   
  "query": { 
   
    "term": { 
   
      "grad_year": "2099"
    }
  },
  "sort": [
    { 
   
      "total_score": { 
   
        "order": "desc"
      }
    }
  ]
}


// stored field 用法
PUT my-index-000001
{ 
   
  "mappings": { 
   
    "properties": { 
   
      "full_name": { 
   
        "type": "text",
        "store": true
      },
      "title": { 
   
        "type": "text",
        "store": true
      }
    }
  }
}

PUT my-index-000001/_doc/1?refresh
{ 
   
  "full_name": "Alice Ball",
  "title": "Professor"
}

GET my-index-000001/_search
{ 
   
  "script_fields": { 
   
    "name_with_title": { 
   
      "script": { 
   
        "lang": "painless",
        "source": "params._fields['title'].value + ' ' + params._fields['full_name'].value"
      }
    }
  }
}

用到脚本的命令

  • function_score
  • script_score
  • aggregation
  • rescore

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/125872.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • painless语法
    • painless基础结构
    • 脚本代码的存储
    • 使用脚本对文档进行更新
    • 脚本变量
    • 脚本缓存
      • 脚本优化
    • 用到脚本的命令
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档