欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

spring-data-mongodb与mongo shell的对应关系

发布时间:2025/3/20 37 豆豆
生活随笔 收集整理的这篇文章主要介绍了 spring-data-mongodb与mongo shell的对应关系 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

除了特殊注释外,本文的测试结果均基于 spring-data-mongodb:1.10.6.RELEASE(spring-boot-starter:1.5.6.RELEASE),MongoDB 3.0.6


   上一章我们了解了mongo shell中aggregate复杂的互相调用关系。那么,spring-data-mongodb中aggregate又是如何与mongo交互的?是将语句拼接成我们熟悉的函数(db._collection_.find/update...)还是命令(db.runCommand)?让我们来看底层的代码到底是怎么样的。

  以下为 mongoTemplate.aggregate 方法的底层实现

private void sendMessage(final CommandMessage message, final InternalConnection connection) {ByteBufferBsonOutput bsonOutput = new ByteBufferBsonOutput(connection);try {int documentPosition = message.encodeWithMetadata(bsonOutput).getFirstDocumentPosition();sendStartedEvent(connection, bsonOutput, message, documentPosition);connection.sendMessage(bsonOutput.getByteBuffers(), message.getId());} finally {bsonOutput.close();}}

   在往下就是字节流了,就直接看着里的数据吧,message数据为:

   test是连接的数据库名称,test.$cmd相当于db.$cmd,有过第二章的基础,这里应该明白,这个方法是走runCommand的$cmd集合的。那么相应的 mongoTemplate.getDb().command 以及 mongoTemplate.getCollection("$cmd").findOne 都可以拼接出来。

  因为这些方法需要的拼接很复杂的bson,所以这里我们引用另外一个操作符$eval。熟悉js的朋友应该都知道,eval是可以将字符串转换成方法执行的,这里我们就使用原生的aggregate语句字符串,让mongo shell去处理字符串。

  如下是五种使用$eval的方法

//注意:命令的key:value部分,value必须被[]或者{}或者''包裹。js的字符串支持单引号和双引号两种,这里使用单引号是为了避免在java中使用大量的 \
     String command = "db.user.aggregate([{$group:{_id:'$name',count:{$sum:'$age'}}}])";BasicDBObject bson = new BasicDBObject();bson.put("$eval",command);Object object1 = mongoTemplate.getDb().doEval(command);Object object2 = mongoTemplate.getDb().command(bson);Object object3 = mongoTemplate.getCollection("$cmd").findOne(bson);ScriptOperations operations = mongoTemplate.scriptOps();ExecutableMongoScript script = new ExecutableMongoScript(command);Object object4 = operations.execute(script);/*** call是调用system.js集合中方法的方法,传入参数是sysytem.js表中数据的主键值,* 可在mongo shell中天插入或者使用如下代码插入。* 插入一次后可直接使用*/ // String command = "function(){return db.user.aggregate([{$group:{_id:'$name',count:{$sum:'$age'}}}])}"; // NamedMongoScript namedMongoScript = new NamedMongoScript("user2",script); // operations.register(namedMongoScript);Object object5 = operations.call("user2");

   那么,find函数是否也如mongo shell 中,让我们继续来看看底层代码

private <T> List<T> executeFindMultiInternal(CollectionCallback<DBCursor> collectionCallback, CursorPreparer preparer,DbObjectCallback<T> objectCallback, String collectionName) {try {DBCursor cursor = null;try {cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));if (preparer != null) {cursor = preparer.prepare(cursor);}List<T> result = new ArrayList<T>();while (cursor.hasNext()) {DBObject object = cursor.next();result.add(objectCallback.doWith(object));}return result;} finally {if (cursor != null) {cursor.close();}}} catch (RuntimeException e) {throw potentiallyConvertRuntimeException(e, exceptionTranslator);}}

  我们可以看到find也如mongo shell中一样,走的是游标的路线。

  通过上面的一系列代码的研究,我们学会了使用多种方法实现原生的aggregate,并且弄明白了aggregate在mongo shell 或者spring-data-mongodb中都存在多层的、暴露的调用方法,而find类型的请求是直接调用到了游标,这样设计的目的是什么?有兴趣的读者可以继续看看第四章 mongo中的游标与数据一致性的取舍。

 


 目录

  一:spring-data-mongodb 使用原生aggregate语句

  二:mongo的runCommand与集合操作函数的关系

  三:spring-data-mongodb与mongo shell的对应关系

  四:mongo中的游标与数据一致性的取舍

转载于:https://www.cnblogs.com/ttjsndx/p/9947370.html

总结

以上是生活随笔为你收集整理的spring-data-mongodb与mongo shell的对应关系的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。