Lucene 表达式

Lucene 表达式 脚本语言 #

Lucene Expressions 是一种轻量级的数学表达式脚本语言,编译为 Java 字节码,性能极高。适用于简单的数值计算场景,如自定义排序和评分。

特点 #

特性说明
性能极高,直接编译为字节码,无解释器开销
安全完全沙盒,只能进行数学运算
功能范围仅支持数值运算和比较
数据访问只能访问 doc values(doc['field']
返回类型始终返回 double

语法 #

基本运算 #

doc['price'].value * 0.9
doc['score'].value + doc['bonus'].value
(doc['a'].value + doc['b'].value) / 2

数学函数 #

函数说明示例
abs(x)绝对值abs(doc['delta'].value)
sqrt(x)平方根sqrt(doc['area'].value)
pow(x, y)x 的 y 次方pow(doc['base'].value, 2)
exp(x)e 的 x 次方exp(-0.01 * doc['age'].value)
ln(x)自然对数ln(doc['count'].value + 1)
log10(x)以 10 为底的对数log10(doc['views'].value + 1)
log2(x)以 2 为底的对数log2(doc['size'].value)
ceil(x)向上取整ceil(doc['score'].value)
floor(x)向下取整floor(doc['score'].value)
max(a, b)较大值max(doc['a'].value, doc['b'].value)
min(a, b)较小值min(doc['a'].value, 100)
sin(x), cos(x), tan(x)三角函数sin(doc['angle'].value)
asin(x), acos(x), atan(x)反三角函数acos(doc['cos_val'].value)
atan2(y, x)二参数反正切atan2(doc['y'].value, doc['x'].value)
haversin(lat1, lon1, lat2, lon2)球面距离(千米)haversin(doc['lat'].value, doc['lon'].value, 39.9, 116.4)

比较与条件 #

Expressions 不支持 if-else,但支持三元运算和布尔转换:

// 布尔值会转为 double(true=1.0, false=0.0)
doc['in_stock'].value ? doc['price'].value : 0

// 比较运算
doc['age'].value > 18 ? 1 : 0

使用示例 #

自定义排序 #

GET products/_search
{
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "lang": "expression",
          "source": "doc['sales'].value * 0.7 + doc['rating'].value * 0.3"
        },
        "order": "desc"
      }
    }
  ]
}

function_score 中使用 #

GET articles/_search
{
  "query": {
    "function_score": {
      "query": { "match": { "title": "搜索" } },
      "script_score": {
        "script": {
          "lang": "expression",
          "source": "_score * ln(doc['views'].value + 1)"
        }
      }
    }
  }
}

地理距离评分 #

GET shops/_search
{
  "query": {
    "function_score": {
      "query": { "match_all": {} },
      "script_score": {
        "script": {
          "lang": "expression",
          "source": "1.0 / (1 + haversin(doc['location'].lat, doc['location'].lon, 39.9042, 116.4074))"
        }
      }
    }
  }
}

Expressions vs Painless #

对比项ExpressionsPainless
性能⚡ 极高⚡ 高
功能范围仅数学运算通用(字符串、数组、条件…)
数据访问仅 doc valuesdoc values + _source + ctx
控制流仅三元运算if/else、for、while
字符串操作
适用场景简单评分/排序公式复杂业务逻辑

建议:如果只需要数值计算(如评分公式、距离计算),优先使用 Expressions 以获得最佳性能。对于需要条件逻辑、字符串处理、数组操作等复杂场景,使用 Painless。

限制 #

  • 只能返回 double 类型的值
  • 只能通过 doc['field'] 访问 doc values 中的数值字段
  • 不支持字符串操作、数组操作
  • 不支持 if-else(只能用三元运算符)
  • 不支持变量声明、循环等语句
  • 不能用于 Update、Ingest 等修改文档的场景