painless语法入门[通俗易懂]

painless语法painless基础结构”script”:{“lang”:”…”,”source”|”id”:”…”,”params”:{…}}lang:定义脚本使用的语言,默认painlesssource,id:脚本的主体,source后面跟着内联的脚本代码,id后面跟着脚本的id,具体代码存在于脚本id对应的代码中params:定义一些变量的值,使用params可以减少脚本的编译次数.因为如果

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

painless语法

painless基础结构


  "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异常.

脚本代码的存储

// 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
        }
      }
    }
  }
}

使用脚本对文档进行更新


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 , 列存储

// 根据分数相加结果进行排序
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.net/125872.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2268大约是多少_情态动词过去式

    2268大约是多少_情态动词过去式小 Q 在电子工艺实习课上学习焊接电路板。一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字 1,2,3… 进行标号。电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两个节点,都存在且仅存在一条通路(通路指连接两个元件的导线序列)。在电路板上存在一个特殊的元件称为“激发器”。当激发器工作后,产生一个激励电流,通过导线传向每一个它所连接的节点。而中间节点接收到激励电流后,得到信息,并将该激励电流传向与它连接并且尚未接收到激励电流的节点。最终,激励电流将到达一些“终止节点”——

    2022年8月9日
    3
  • 浅析如何把ER模型转换为关系模式

    浅析如何把ER模型转换为关系模式本篇文章讲解的内容是“浅析如何把ER模型转换为关系模式”。在做ER图题目时,有些同学还是经常会做错,最主要原因是没有理解他们之间转换的原理。本文通过理论分析和例题来浅析这块知识点,当理解后,可以趁热打铁,把后面推荐的例题题目做一下,即可完全吸收这块内容。

    2022年7月16日
    16
  • Java设计模式菜鸟系列(两)建模与观察者模式的实现

    Java设计模式菜鸟系列(两)建模与观察者模式的实现

    2022年1月12日
    46
  • PyQt5高级界面控件之QTableWidget(四)

    PyQt5高级界面控件之QTableWidget(四)QTableWidget前言QTableWidget是Qt程序中常用的显示数据表格的控件,类似于c#中的DataGrid。QTableWidget是QTableView的子类,它使用标准的数据模型,并且其单元数据是通过QTableWidgetItem对象来实现的,使用QTableWidget时就需要QTableWidgetItem。用来表示表格中的一个单元格,整个表格就是用各个单元格构建起…

    2022年5月3日
    46
  • 正态分布方差推导_均匀分布的期望和方差公式

    正态分布方差推导_均匀分布的期望和方差公式概论:一维随机变量期望与方差二维随机变量期望与方差协方差1.一维随机变量期望与方差:公式:离散型:E(X)=∑i=1->nXiPiY=g(x)E(Y)=∑i=1->ng(x)Pi连续型:E(X)=∫-∞->+∞xf(x)dxY=g(x)E(Y)=∫-∞->+∞g(x)f(x)dx方差:D(x)=E(x²)-E²(x)标准差:根号下的方差常用分布的数学期望和方差:0~1分布…

    2022年9月17日
    0
  • 自己动手写操作系统–个人实践「建议收藏」

    自己动手写操作系统–个人实践「建议收藏」最近开始看于渊的《自己动手写操作系统》这本书,刚开始看就发现做系统的引导盘竟然是软盘!心里那个汗啊!现在都是U盘了,谁还用软盘。于是考虑用U盘。于是开始以下步骤:1、既然书上说给先要把软盘做引导盘,那我就类似地把U盘做成引导盘。在网上找了半天,发现USboot,于是就用它给自己的U盘做了一个引导盘。2、把编译后的boot.bin文件用绝对扇区工具写入U盘就万事大吉了。同样,在网上找

    2022年10月21日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号