Mongo 4.0移除db.eval后,如何用MongoClient运行原生脚本?
替代db.eval()在MongoClient中运行查询的方案
MongoDB 4.0移除db.eval()后,可通过以下方式实现类似需求,完全兼容MongoClient的使用逻辑:
1. 优先使用驱动原生API执行标准查询
对于常规的查询、更新、聚合操作,直接用MongoCollection提供的强类型API是最优选择,比脚本执行更安全高效:
final String mongoUri = buildMongoURI(connectionUri, username, password); try (MongoClient mongoClient = MongoClients.create(mongoUri)) { MongoDatabase db = mongoClient.getDatabase(findDatabaseNameInMongoURI(mongoUri)); MongoCollection<Document> coll = db.getCollection("deploy"); // 执行find查询 FindIterable<Document> queryResults = coll.find(Filters.eq("by", "tutorials point")); for (Document doc : queryResults) { System.out.println(doc.toJson()); } // 执行聚合查询示例 List<Bson> pipeline = Arrays.asList( Aggregates.match(Filters.eq("by", "tutorials point")), Aggregates.group("$by", Accumulators.sum("count", 1)) ); AggregateIterable<Document> aggResults = coll.aggregate(pipeline); for (Document doc : aggResults) { System.out.println(doc.toJson()); } }
2. 使用runCommand执行MongoDB原生命令
runCommand支持执行所有MongoDB原生命令,Document本身就是Bson接口的实现类,你之前的代码问题在于传递的不是有效命令文档。比如要查看查询执行计划,可构造explain命令:
final String mongoUri = buildMongoURI(connectionUri, username, password); try (MongoClient mongoClient = MongoClients.create(mongoUri)) { MongoDatabase db = mongoClient.getDatabase(findDatabaseNameInMongoURI(mongoUri)); // 构造有效的explain命令 Document explainCommand = Document.parse("{" + " explain: {" + " find: 'deploy'," + " filter: {by: 'tutorials point'}" + " }," + " verbosity: 'queryPlanner'" + "}"); Document executionPlan = db.runCommand(explainCommand); System.out.println(executionPlan.toJson()); }
3. 执行自定义JS逻辑(MongoDB 4.4+)
如果确实需要执行自定义JavaScript逻辑,可使用聚合管道的$function操作符替代原db.eval()的脚本执行场景:
final String mongoUri = buildMongoURI(connectionUri, username, password); try (MongoClient mongoClient = MongoClients.create(mongoUri)) { MongoDatabase db = mongoClient.getDatabase(findDatabaseNameInMongoURI(mongoUri)); MongoCollection<Document> coll = db.getCollection("deploy"); List<Bson> pipeline = Arrays.asList( Aggregates.match(Filters.eq("by", "tutorials point")), Aggregates.project(Document.parse("{" + " upperCaseBy: {" + " $function: {" + " body: function(doc) { return doc.by.toUpperCase(); }," + " args: ['$$ROOT']," + " lang: 'js'" + " }" + " }" + "}")) ); AggregateIterable<Document> results = coll.aggregate(pipeline); for (Document doc : results) { System.out.println(doc.toJson()); } }
注意事项
- 避免使用脚本执行类操作,存在注入风险且性能低于原生API;
- 所有MongoDB命令都可通过
runCommand执行,命令格式需符合官方定义; - 驱动提供的
Filters、Aggregates等工具类可简化Bson构造,减少字符串解析错误。
内容的提问来源于stack exchange,提问作者Mahesh K G
相关产品推荐
相关产品推荐

