MongoDB 3.4 Java驱动:JSON数组转List<? extends Bson>最优方法
嘿,这个问题我刚好碰到过,给你捋捋怎么解决!
你遇到的核心点是:aggregate()需要的是多个Bson对象组成的列表,而find()只需要单个Bson对象,所以Document.parse()能直接用在find上,但处理数组就得换个方式了。
在MongoDB 3.4的Java驱动里,Document本身就实现了Bson接口,所以只要把你的JSON数组字符串解析成List<Document>,就能直接传给aggregate()方法。
下面给两种常用的实现方式:
方法一:用Jackson解析(推荐,更灵活)
如果你的项目已经引入了Jackson依赖,直接用它来把JSON数组转成List<Document>:
import com.mongodb.client.MongoCollection; import org.bson.Document; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; // 你的JSON管道字符串 String pipelineJson = "[ { \"abc\" : \"123\" }, { \"def\" : \"456\" } ]"; ObjectMapper mapper = new ObjectMapper(); List<Document> pipeline; try { // 把JSON数组解析成Document列表 pipeline = mapper.readValue(pipelineJson, new TypeReference<List<Document>>() {}); } catch (Exception e) { // 处理JSON格式错误的情况 e.printStackTrace(); return; } // 直接调用aggregate mongoCollection.aggregate(pipeline);
方法二:用MongoDB自带的JSON工具类
如果不想引入Jackson,也可以用MongoDB驱动自带的JSON工具类来解析:
import com.mongodb.client.MongoCollection; import com.mongodb.util.JSON; import org.bson.BasicDBList; import org.bson.BasicDBObject; import org.bson.Document; import java.util.List; import java.util.stream.Collectors; String pipelineJson = "[ { \"abc\" : \"123\" }, { \"def\" : \"456\" } ]"; // 解析成BasicDBList(MongoDB的原生列表类型) BasicDBList dbList = (BasicDBList) JSON.parse(pipelineJson); // 转成List<Document> List<Document> pipeline = dbList.stream() .map(item -> new Document((BasicDBObject) item)) .collect(Collectors.toList()); // 调用aggregate mongoCollection.aggregate(pipeline);
为什么这两种方法可行?
因为Document类实现了Bson接口,所以List<Document>完全符合List<? extends Bson>的参数要求,直接就能被aggregate()方法接受。
对比find()方法:它只需要单个Bson对象,所以用Document.parse()把单个JSON字符串转成Document(也就是Bson)就足够了,但aggregate()是管道操作,需要多个阶段,所以得解析成列表才行。
内容的提问来源于stack exchange,提问作者Doctor White
相关产品推荐
相关产品推荐

