如何用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; } } }
代码说明
- 根节点处理:
processJsonForMongo方法负责解析原始JSON的根结构,生成MongoDB要求的_id、field和value外层包装。 - 递归过滤与转换:
processNestedObject方法递归处理所有嵌套的JSON对象和数组:- 遇到
component为containers/EmptyContainer.vue的对象时,仅保留其children字段(若存在),丢弃其他无关字段 - 处理数组时,遍历每个元素并过滤掉空结果,确保数组结构干净
- 基本类型直接返回,不做修改
- 遇到
- 结果合并:递归处理后的结果会自动合并到当前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
相关产品推荐
相关产品推荐

