场景:需要筛选出更新时间update_time和创建时间create_time相差1天的数据

涉及的字段类型: date --被存储为一个长整型数字,代表从1970年1月1号0点到现在的毫秒数,

通常使用RangeQuery查询的时候会在内部被转为对long型值的范围查询,所以想到的方法是将date类型的数据转换为数字,再进行比较;

应用到的方法:script脚本查询;

"script": {
    "lang": "xxx",//language的意思,指定脚本是用哪种语言写的,值可以是painless、expression,默认是painless
    "source": "xxx",//脚本
    "params": {xxx}//参数
}

script脚本查询的神奇之处在于几乎和写Java方法无异,各类数据类型对应的类方法都支持,比如string类型的substring(),trim(),contains()等等;时间date类型涉及的相关方法有:toInstant()获取长整型数字,toEpochMilli()获取对应的毫秒数等等;

具体查询:

"query":{
        "script": {
            "script" : {
                "source": "doc['update_time'].size() > 0 && doc['create_time'].size() > 0 
&& (doc['update_time'].value.toInstant().toEpochMilli() - doc['create_time'].value.toInstant().toEpochMilli() > params.num)",
                "lang": "painless",
                "params": {
                    "num":"86400000"
                }
            }
        }
    }

doc是个关键字,表示文档;doc['']是指定某个字段,value是个关键字,指的是字段的值; size() > 0 表示字段不为空,也可以.value != null;

以上是说当两个字段都不为空时,取时间的毫秒数进行计算比较,大于1天的;

Java 中实现:

private BoolQueryBuilder test(long time, String startTime, String endTime) throws ParseException {
    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
    boolQueryBuilder.filter(QueryBuilders.rangeQuery("create_time").gte(startTime).lte(endTime));
    boolQueryBuilder.filter(QueryBuilders.scriptQuery(new Script("doc['update_time'].size() > 0 && doc['create_time'].size() > 0 
&& (doc['update_time'].value.toInstant().toEpochMilli() - doc['create_time'].value.toInstant().toEpochMilli() > " + time + ")")));
   
 
    return boolQueryBuilder ;
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐