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

如何用Java将嵌套JSON插入MongoDB并过滤指定组件

问题描述

我有一个嵌套结构的JSON文件,原始结构如下:

{
  "databases": {
    "component": "pages/dems/transparency/workspaces/DatasourcesWorkspace.vue",
    "children": [
      {
        "name": "Databases",
        "path": "databases",
        "component": "pages/dems/transparency/workspaces/Databases.vue",
        "hide": true,
        "help": "context-sensitive-help/transparency/workspaces/datasources/databases/databases/databases.html"
      },
      {
        "name": "Schemas",
        "path": "schemas",
        "component": "containers/EmptyContainer.vue",
        "hide": true,
        "children": [
          {
            "name": "",
            "component": "pages/dems/transparency/workspaces/Schemas.vue",
            "hide": true,
            "help": "context-sensitive-help/transparency/workspaces/datasources/databases/schemas.html"
          },
          {
            "name": "",
            "path": "relationship/:id",
            "component": "pages/dems/transparency/workspaces/profilecolumn/ViewRelationShip.vue",
            "hide": true,
            "help": "context-sensitive-help/transparency/workspaces/relationship/relationship.html"
          }
        ]
      }
    ]
  }
}

需要将其转换为如下结构后插入MongoDB,同时过滤掉所有component值为containers/EmptyContainer.vue的对象:

{
    "_id":"id1",
    "field":"databases",
    "value":{
        "component": "pages/dems/transparency/workspaces/DatasourcesWorkspace.vue",
        "children": [
          {
            "name": "Databases",
            "path": "databases",
            "component": "pages/dems/transparency/workspaces/Databases.vue",
            "hide": true,
            "help": "context-sensitive-help/transparency/workspaces/datasources/databases/databases/databases.html"
          },
          {
            "children": [
              {
                "name": "",
                "component": "pages/dems/transparency/workspaces/Schemas.vue",
                "hide": true,
                "help": "context-sensitive-help/transparency/workspaces/datasources/databases/schemas.html"
              },
              {
                "name": "",
                "path": "relationship/:id",
                "component": "pages/dems/transparency/workspaces/profilecolumn/ViewRelationShip.vue",
                "hide": true,
                "help": "context-sensitive-help/transparency/workspaces/relationship/relationship.html"
              }
            ]
          }
        ]
      }
}

我尝试了以下Java代码,但没有达到预期效果:

public ArrayList<Document> processJsonV4(Object source) throws JSONException {
    ArrayList<Document> rootDoc = new ArrayList<>();
    if (source instanceof JSONObject) {
        JSONObject jsonObject = (JSONObject) source;
        Document document = new Document();
        if (jsonObject.has("component") && !"containers/EmptyContainer.vue".equals(jsonObject.getString("component"))) {
            for (Iterator keys = jsonObject.keys(); keys.hasNext(); ) {
                String key = (String) keys.next();
                Object value = jsonObject.get(key);
                document.append(key, value);
            }

        } else {
            for (Iterator keys = jsonObject.keys(); keys.hasNext(); ) {
                String key = (String) keys.next();
                Object value = jsonObject.get(key);
                processJsonV4(value);
            }
        }
        rootDoc.add(document);
    }
    KLogger.info("RootDoc: " + rootDoc);
    return rootDoc;
}

请问如何用Java实现该需求?


解决方案

你的现有代码存在三个核心问题:

  • 未处理JSON数组(比如children),导致嵌套子结构无法被递归处理
  • 递归调用结果未合并到当前Document中,丢失了处理后的嵌套数据
  • 未按照目标结构生成_id、field和value的外层包装

以下是修正后的代码,完全实现需求:

import org.bson.Document;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;

public class JsonProcessor {

    public Document processJsonForMongo(JSONObject originalJson) throws JSONException {
        // 提取根节点的key作为field值(这里默认根节点只有一个key,如示例中的databases)
        Iterator<String> rootKeys = originalJson.keys();
        String fieldKey = rootKeys.next();
        JSONObject rootValue = originalJson.getJSONObject(fieldKey);

        // 构建MongoDB要求的最终文档结构
        Document resultDoc = new Document();
        resultDoc.append("_id", "id1"); // 可根据业务逻辑替换为动态生成的ID
        resultDoc.append("field", fieldKey);
        resultDoc.append("value", processNestedObject(rootValue));

        return resultDoc;
    }

    private Object processNestedObject(Object source) throws JSONException {
        if (source instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) source;
            Document processedDoc = new Document();

            // 过滤EmptyContainer对象,仅保留其children字段(如果存在)
            if (jsonObj.has("component") && "containers/EmptyContainer.vue".equals(jsonObj.getString("component"))) {
                return jsonObj.has("children") ? processNestedObject(jsonObj.get("children")) : null;
            }

            // 遍历所有键值对,递归处理每个值
            Iterator<String> keys = jsonObj.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                Object value = jsonObj.get(key);
                Object processedValue = processNestedObject(value);
                if (processedValue != null) {
                    processedDoc.append(key, processedValue);
                }
            }

            return processedDoc;
        } else if (source instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) source;
            ArrayList<Object> processedList = new ArrayList<>();

            // 遍历数组元素,递归处理并过滤空结果
            for (int i = 0; i < jsonArray.length(); i++) {
                Object item = jsonArray.get(i);
                Object processedItem = processNestedObject(item);
                if (processedItem != null) {
                    processedList.add(processedItem);
                }
            }

            return processedList;
        } else {
            // 基本类型(字符串、布尔值等)直接返回
            return source;
        }
    }
}

代码说明

  1. 根节点处理:processJsonForMongo方法负责解析原始JSON的根结构,生成MongoDB要求的_id、field和value外层包装。
  2. 递归过滤与转换:processNestedObject方法递归处理所有嵌套的JSON对象和数组:
    • 遇到component为containers/EmptyContainer.vue的对象时,仅保留其children字段(若存在),丢弃其他无关字段
    • 处理数组时,遍历每个元素并过滤掉空结果,确保数组结构干净
    • 基本类型直接返回,不做修改
  3. 结果合并:递归处理后的结果会自动合并到当前Document或数组中,保证最终结构完全符合目标要求

使用示例

public static void main(String[] args) throws JSONException {
    // 替换为你的原始JSON字符串
    String originalJsonStr = "{\"databases\": {\"component\": \"pages/dems/transparency/workspaces/DatasourcesWorkspace.vue\",\"children\": [{\"name\": \"Databases\",\"path\": \"databases\",\"component\": \"pages/dems/transparency/workspaces/Databases.vue\",\"hide\": true,\"help\": \"context-sensitive-help/transparency/workspaces/datasources/databases/databases/databases.html\"},{\"name\": \"Schemas\",\"path\": \"schemas\",\"component\": \"containers/EmptyContainer.vue\",\"hide\": true,\"children\": [{\"name\": \"\",\"component\": \"pages/dems/transparency/workspaces/Schemas.vue\",\"hide\": true,\"help\": \"context-sensitive-help/transparency/workspaces/datasources/databases/schemas.html\"},{\"name\": \"\",\"path\": \"relationship/:id\",\"component\": \"pages/dems/transparency/workspaces/profilecolumn/ViewRelationShip.vue\",\"hide\": true,\"help\": \"context-sensitive-help/transparency/workspaces/relationship/relationship.html\"}]}]}}";
    
    JSONObject originalJson = new JSONObject(originalJsonStr);
    JsonProcessor processor = new JsonProcessor();
    Document mongoDoc = processor.processJsonForMongo(originalJson);
    
    // 输出处理后的结果,可直接插入MongoDB
    System.out.println(mongoDoc.toJson());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:05:27