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

如何在Elasticsearch Java Client 8的msearch请求中使用script_fields

Elasticsearch Java Client 8 实现多搜索(Multi Search)请求

要实现你提供的多搜索请求,核心是为每个单独的SearchRequest配置查询条件和脚本字段,再将这些请求组装到MultiSearchRequest中执行。以下是具体代码实现:

1. 构建查询条件和脚本字段

首先,针对每个搜索请求,构建地理距离过滤、布尔查询,以及计算距离的脚本字段:

// 定义目标坐标(用于geo_distance过滤)
double targetLat = 12.9322;
double targetLon = 77.6904;

// 定义脚本字段中用于计算距离的坐标
double scriptLat = 40.00327;
double scriptLon = 15.36496;

// 构建地理距离过滤条件
GeoDistanceQuery geoDistanceQuery = GeoDistanceQuery.of(g -> g
    .field("latLon")
    .distance("3km")
    .distanceType(GeoDistanceType.Arc)
    .location(l -> l.lat(targetLat).lon(targetLon))
);

// 构建布尔查询
BoolQuery boolQuery = BoolQuery.of(b -> b
    .must(m -> m.matchAll(m2 -> m2))
    .filter(f -> f.geoDistance(geoDistanceQuery))
);

// 构建脚本字段(参数化写法避免注入风险)
ScriptField distanceScriptField = ScriptField.of(s -> s
    .script(sc -> sc.inline(i -> i
        .source("doc['latLon'].arcDistance(params.lat, params.lon)")
        .params("lat", scriptLat)
        .params("lon", scriptLon)
    ))
);

2. 组装单个搜索请求

将上述查询和脚本字段绑定到SearchRequest,每个请求可独立配置:

// 第一个搜索请求
SearchRequest searchRequest1 = SearchRequest.of(s -> s
    .index("your-index-name") // 替换为你的索引名
    .query(q -> q.bool(boolQuery))
    .scriptFields(fields -> fields.put("distance_in_m", distanceScriptField))
);

// 第二个搜索请求(逻辑与第一个一致,可复用查询和脚本字段)
SearchRequest searchRequest2 = SearchRequest.of(s -> s
    .index("your-index-name") // 替换为你的索引名
    .query(q -> q.bool(boolQuery))
    .scriptFields(fields -> fields.put("distance_in_m", distanceScriptField))
);

3. 组装并执行多搜索请求

将多个SearchRequest添加到MultiSearchRequest,通过客户端执行并处理结果:

// 初始化Elasticsearch客户端(需提前完成配置)
ElasticsearchClient client = new ElasticsearchClient(/* 你的客户端配置 */);

// 构建多搜索请求
MultiSearchRequest multiSearchRequest = MultiSearchRequest.of(m -> m
    .operations(op -> op.search(searchRequest1))
    .operations(op -> op.search(searchRequest2))
);

// 执行请求
MultiSearchResponse response = client.msearch(multiSearchRequest);

// 遍历处理响应结果
for (MultiSearchResponse.Item item : response.items()) {
    if (item.isFailure()) {
        System.out.println("请求失败: " + item.failure().reason());
        continue;
    }
    SearchResult result = item.result();
    for (Hit<Object> hit : result.hits().hits()) {
        Object distance = hit.fields().get("distance_in_m").value();
        System.out.println("文档ID: " + hit.id() + ",计算距离: " + distance + "米");
    }
}

关键说明

  • 每个SearchRequest通过scriptFields(fields -> fields.put(...))方法独立配置脚本字段,这就是8.x版本中为单个查询添加脚本字段的方式。
  • 脚本采用参数化写法而非直接拼接字符串,能有效避免脚本注入风险,适合动态传入坐标的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:17:15