You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将OpenSearch日期过滤Painless脚本转换为Java代码?

将OpenSearch日期过滤Painless脚本集成到Fess Java代码

问题背景

需要把一段按日、月、年维度过滤日期的OpenSearch Painless脚本,集成到基于org.codelibs.fess:fess:14.4.0开发的Java代码中,已完成部分初始化代码,但不清楚如何正确嵌入Painless脚本内容。

解决方案

1. 处理Painless脚本的字符串转义

由于Java字符串对双引号和换行有语法要求,需将原Painless脚本转换为Java可识别的格式。推荐使用Java文本块(Java 15+)避免繁琐转义,也可对双引号手动转义。

转换后的Painless脚本Java字符串(文本块版本):

String painlessScript = """
    int day;
    int month;
    int year;
    
    if ((int) doc['decisionDate.decisionDay'].size() > 0 && (int) doc['decisionDate.decisionMonth'].size() > 0 && (int) doc['decisionDate.decisionYear'].size() > 0) {
        day = (int) doc['decisionDate.decisionDay'].value;
        month = (int) doc['decisionDate.decisionMonth'].value;
        year = (int) doc['decisionDate.decisionYear'].value;
        
        return ChronoUnit.DAYS.between(ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of('Z')), 
                ZonedDateTime.of(2022, 12, 13, 0, 0, 0, 0, ZoneId.of('Z'))) > 0 && 
               ChronoUnit.DAYS.between(ZonedDateTime.of(2011, 03, 30, 0, 0, 0, 0, ZoneId.of('Z')), 
                ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of('Z'))) > 0;
    }
    // 字段缺失时返回false,避免脚本报错
    return false;
""";

2. 完整的Fess Java集成代码

将脚本传入LanguageHelper.createScript,再构建查询条件并执行搜索:

final SearchEngineClient searchEngineClient = ComponentUtil.getSearchEngineClient();
final FessConfig fessConfig = ComponentUtil.getFessConfig();
final LabelTypeHelper labelTypeHelper = ComponentUtil.getLabelTypeHelper();
final LanguageHelper languageHelper = ComponentUtil.getLanguageHelper();

// 定义Painless脚本
String painlessScript = """
    int day;
    int month;
    int year;
    
    if ((int) doc['decisionDate.decisionDay'].size() > 0 && (int) doc['decisionDate.decisionMonth'].size() > 0 && (int) doc['decisionDate.decisionYear'].size() > 0) {
        day = (int) doc['decisionDate.decisionDay'].value;
        month = (int) doc['decisionDate.decisionMonth'].value;
        year = (int) doc['decisionDate.decisionYear'].value;
        
        return ChronoUnit.DAYS.between(ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of('Z')), 
                ZonedDateTime.of(2022, 12, 13, 0, 0, 0, 0, ZoneId.of('Z'))) > 0 && 
               ChronoUnit.DAYS.between(ZonedDateTime.of(2011, 03, 30, 0, 0, 0, 0, ZoneId.of('Z')), 
                ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of('Z'))) > 0;
    }
    return false;
""";

// 创建Script对象
Script script = languageHelper.createScript(painlessScript);

// 构建脚本查询过滤器
ScriptQueryBuilder scriptQuery = QueryBuilders.scriptQuery(script);

// 构建Bool查询,添加must条件
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().must(scriptQuery);

// 构建搜索请求,指定Fess索引
SearchRequest searchRequest = new SearchRequest(fessConfig.getIndexDocumentSearchIndex());
searchRequest.source(new SearchSourceBuilder().query(boolQuery));

// 执行搜索并处理结果
try {
    SearchResponse searchResponse = searchEngineClient.search(searchRequest);
    // 此处添加搜索结果的业务处理逻辑
} catch (IOException e) {
    // 捕获并处理搜索异常
    e.printStackTrace();
}

关键说明

  • 补充了字段缺失时的返回逻辑(return false),避免脚本因字段不存在抛出异常。
  • 使用QueryBuilders构建查询条件,完全适配Fess依赖的OpenSearch客户端API规范。
  • SearchEngineClient是Fess封装的搜索客户端,直接调用其search方法即可执行请求。

内容的提问来源于stack exchange,提问作者Dona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:45:30