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

如何用Java从Elasticsearch任务响应中提取无键节点ID?

从Elasticsearch任务响应中提取任务ID的Java实现方案

针对你需要从Elasticsearch运行任务响应JSON中提取类似ZKUuxQZpRCCcJ0njBM1P0A:118这类任务ID的需求,我整理了两种可行的实现方案:

方案1:使用Java JSON解析器(以Jackson为例)

你提到的动态键问题确实是个小难点,不过我们可以用Map结构来接收这些动态内容,不用硬编码响应类。这里以常用的Jackson库为例:

首先确保项目引入Jackson依赖(Maven示例):

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

然后编写解析代码:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class EsTaskParser {
    public static void main(String[] args) throws IOException {
        String jsonResponse = "{ \"nodes\": { \"ZKUuxQZpRCCcJ0njBM1P0A\": { \"name\": \"ZKUuxQZ\", \"transport_address\": \"127.0.0.1:9300\", \"host\": \"127.0.0.1\", \"ip\": \"127.0.0.1:9300\", \"roles\": [ \"master\", \"data\", \"ingest\" ], \"tasks\": { \"ZKUuxQZpRCCcJ0njBM1P0A:118\": { \"node\": \"ZKUuxQZpRCCcJ0njBM1P0A\", \"id\": 118, \"type\": \"transport\", \"action\": \"indices:data/write/delete/byquery\", \"start_time_in_millis\": 1527808643421, \"running_time_in_nanos\": 154234724059, \"cancellable\": true, \"headers\": {} } } } } }";

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(jsonResponse);
        JsonNode nodesNode = rootNode.get("nodes");
        
        List<String> taskIds = new ArrayList<>();
        
        // 遍历所有节点
        nodesNode.fields().forEachRemaining(nodeEntry -> {
            JsonNode tasksNode = nodeEntry.getValue().get("tasks");
            if (tasksNode != null && !tasksNode.isNull()) {
                // 遍历当前节点下的所有任务,键就是我们要的任务ID
                tasksNode.fields().forEachRemaining(taskEntry -> {
                    taskIds.add(taskEntry.getKey());
                });
            }
        });
        
        // 输出结果:["ZKUuxQZpRCCcJ0njBM1P0A:118"]
        System.out.println(taskIds);
    }
}

这种方式的优势是精准匹配,不会受到JSON格式变动(比如空格、换行)的影响,比正则表达式更可靠。

方案2:使用正则表达式

你原来的正则已经基本可用,我帮你优化了一下,确保只匹配tasks对象下的键(也就是被双引号包裹的目标字符串),避免误匹配其他位置的类似格式内容:

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EsTaskRegexParser {
    public static void main(String[] args) {
        String jsonResponse = "{ \"nodes\": { \"ZKUuxQZpRCCcJ0njBM1P0A\": { \"name\": \"ZKUuxQZ\", \"transport_address\": \"127.0.0.1:9300\", \"host\": \"127.0.0.1\", \"ip\": \"127.0.0.1:9300\", \"roles\": [ \"master\", \"data\", \"ingest\" ], \"tasks\": { \"ZKUuxQZpRCCcJ0njBM1P0A:118\": { \"node\": \"ZKUuxQZpRCCcJ0njBM1P0A\", \"id\": 118, \"type\": \"transport\", \"action\": \"indices:data/write/delete/byquery\", \"start_time_in_millis\": 1527808643421, \"running_time_in_nanos\": 154234724059, \"cancellable\": true, \"headers\": {} } } } } }";

        // 正则说明:匹配被双引号包裹的、由字母数字下划线短横线+冒号+数字组成的字符串
        // 通过 (?<=tasks":\s*{) 确保只匹配tasks对象内的键
        Pattern pattern = Pattern.compile("(?<=tasks\":\\s*{)\\s*\"([a-zA-Z0-9_-]+:[0-9]+)\"");
        Matcher matcher = pattern.matcher(jsonResponse);
        
        List<String> taskIds = new ArrayList<>();
        while (matcher.find()) {
            taskIds.add(matcher.group(1));
        }
        
        // 输出结果:["ZKUuxQZpRCCcJ0njBM1P0A:118"]
        System.out.println(taskIds);
    }
}

如果JSON中tasks包含多个任务,这个正则也能全部匹配到。不过要注意,如果JSON的格式有较大变动(比如tasks的位置或结构变化),正则可能会失效,所以更推荐方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:55:48