如何在Java中使用JSON文件实现MongoDB聚合操作(基于MongoDB Java Driver 4.3)
解决MongoDB Java Driver 4.3将JSON聚合管道转成List的问题
刚好我对MongoDB Java Driver 4.x版本的聚合管道处理比较熟悉,我来帮你搞定这个问题!
首先要注意:你直接用new File(fileName)读取src/main/resources下的文件,在IDE里可能没问题,但项目打包成JAR后会失效——因为JAR里的资源不是磁盘上的物理文件。所以第一步我们要先正确读取resources目录下的JSON文件,再把JSON内容解析成List<Bson>。
步骤1:读取resources中的JSON文件内容
用类加载器获取资源并读取为字符串,这种方式在IDE和JAR包环境下都能正常工作:
import java.nio.file.Files; import java.nio.file.Paths; import java.util.Objects; String fileName = "physics/test.json"; // 从resources中获取文件并读取为字符串 String jsonPipeline = Files.readString( Paths.get(Objects.requireNonNull( YourClassName.class.getClassLoader().getResource(fileName) ).toURI()) );
记得把YourClassName替换成你实际的类名
步骤2:将JSON字符串解析为List
MongoDB Java Driver提供了专门的工具类处理JSON和Bson的转换,这里给你两种方案:
方案一:官方标准解析方式
借助CodecRegistry和JsonReader完成解析,兼容性最好:
import org.bson.Bson; import org.bson.BsonDocument; import org.bson.BsonType; import org.bson.codecs.DecoderContext; import org.bson.codecs.configuration.CodecRegistry; import org.bson.json.JsonReader; import com.mongodb.MongoClients; import java.util.ArrayList; import java.util.List; // 获取默认的Codec注册表 CodecRegistry codecRegistry = MongoClients.getDefaultCodecRegistry(); JsonReader jsonReader = new JsonReader(jsonPipeline); List<Bson> pipeline = new ArrayList<>(); // 开始读取JSON数组 jsonReader.readStartArray(); // 逐个读取数组中的每个聚合阶段 while (jsonReader.readBsonType() != BsonType.END_OF_DOCUMENT) { BsonDocument bsonDoc = codecRegistry.get(BsonDocument.class) .decode(jsonReader, DecoderContext.builder().build()); pipeline.add(bsonDoc); } jsonReader.readEndArray();
方案二:简洁中转解析方式
借助Document中转,代码更简洁,适合快速开发:
import org.bson.Document; import org.bson.Bson; import java.util.List; import java.util.stream.Collectors; // 把JSON数组包装到临时Document中,方便解析 Document tempDoc = Document.parse("{ pipeline: " + jsonPipeline + " }"); // 提取数组并转成List<Bson> List<Bson> pipeline = tempDoc.getList("pipeline", Document.class) .stream() .map(doc -> (Bson) doc) .collect(Collectors.toList());
完整代码整合
把上述逻辑整合到你的原有代码中,最终版本如下:
import com.mongodb.client.AggregateIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoClients; import org.bson.Bson; import org.bson.Document; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; public class YourAggregationClass { private static final String DATABASE_NAME = "your_db_name"; public void runAggregation(String collectionName) { String fileName = "physics/test.json"; try { // 1. 读取resources中的JSON管道内容 String jsonPipeline = Files.readString( Paths.get(Objects.requireNonNull( YourAggregationClass.class.getClassLoader().getResource(fileName) ).toURI()) ); // 2. 解析为List<Bson>(这里用简洁版方案) Document tempDoc = Document.parse("{ pipeline: " + jsonPipeline + " }"); List<Bson> pipeline = tempDoc.getList("pipeline", Document.class) .stream() .map(doc -> (Bson) doc) .collect(Collectors.toList()); // 3. 执行聚合 MongoDatabase db = MongoClients.create().getDatabase(DATABASE_NAME); MongoCollection<Document> collection = db.getCollection(collectionName); AggregateIterable<Document> sourceList = collection.aggregate(pipeline); // 后续处理聚合结果... } catch (Exception e) { e.printStackTrace(); } } }
注意事项
- 确保你的JSON文件内容是合法的JSON数组,格式类似:
[{$match: {field: value}}, {$group: {_id: "$field", count: {$sum: 1}}}] - 如果你用的是MongoDB Java Driver 4.3.1,所有依赖的类都是核心包自带的,不需要额外引入其他依赖
内容的提问来源于stack exchange,提问作者khateeb
相关产品推荐
相关产品推荐

