除了特殊注释外,本文的测试结果均基于 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的对应关系相关推荐

  1. mongo java 注解,在Java中使用Spring Data MongoDB操作Mong | zifangsky的个人博客

    前言:在上一篇文章中(PS:https://www.zifangsky.cn/923.html)我简单介绍了如何在Linux中安装MongoDB以及MongoDB的增删改查等基本命令用法(PS:更多M ...

  2. mongo java 日期,Java 8日期/时间(JSR-310)类型与Spring Data MongoDB的映射

    我有Java 8日期/时间字段的简单文档 @Document public class Token { private Instant createdAt; ... } 我希望坚持使用Spring D ...

  3. 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南

    1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...

  4. Spring Data MongoDB级联保存在DBRef对象上

    默认情况下, Spring Data MongoDB不支持对带有@DBRef注释的引用对象的级联操作,如引用所述 : 映射框架不处理级联保存 . 如果更改了Person对象引用的Account对象,则 ...

  5. Spring Data MongoDB中的审核实体

    Spring Data MongoDB 1.2.0静默引入了新功能:支持基本审核 . 因为您不会在本文的官方参考中找到太多有关它的信息,所以我将展示它带来的好处,如何配置Spring以进行审计以及如何 ...

  6. 使用NoSQLUnit测试Spring Data MongoDB应用程序

    Spring Data MongoDB是Spring Data项目中的项目,它提供了Spring编程模型的扩展,用于编写使用MongoDB作为数据库的应用程序. 要使用NoSQLUnit为Spring ...

  7. Spring Data MongoDB示例

    Spring Data MongoDB示例 欢迎使用Spring Data MongoDB示例.Spring Data MongoDB是将Spring Framework与最广泛使用的NoSQL数据库 ...

  8. SpringBoot 集成 Spring Data Mongodb 操作 MongoDB 详解

    一.MongoDB 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,且与关系数据库的最为相像的.它支持的数据结构非常松散,是类似 json 的 bso ...

  9. mongodb数据库java接口,MongoDB —— 使用Spring Data MongoDB操作数据库

    我们使用Spring Data MongoDB可以方便的在Spring boot项目中操作MongoDB 文档地址:https://docs.spring.io/spring-boot/docs/2. ...

最新文章

  1. predictor = dlib.shape_predictor()关键点预测器用法
  2. android 置灰不可点击,Android Studio 运行按钮灰色的完美解决方法
  3. 用开关控制蜂鸣器_室内照明控制系统的调试与检修
  4. hdu 6112 今夕何夕
  5. JS 实现图片的预加载(转载)
  6. java.util.NoSuchElementException: No value present
  7. java 指针_java多线程学习二十二:::java中的指针
  8. 数据库 实体间的3种关系
  9. c++ vector拷贝构造_JDK源码分析-Vector
  10. nginx添加第三方模块,以及启用nginx本身支持的模块
  11. 【王道操作系统笔记】操作系统的四个特征
  12. 用bat命令重启explorer的方法
  13. Windows 10原创知识题(第四版)
  14. Windows Server 2008打印服务器安装与配置
  15. eclipse 注销快捷键
  16. 怎么把一个PDF文件拆分成多个?
  17. 网页设计-动态雪花背景源码
  18. 2WD远程控制小车——云端设计
  19. python跨平台是什么意思_跨平台是什么意思?通俗深刻的解释
  20. 人民币符号怎么打?美元符号怎么打?

热门文章

  1. 网络爬虫:基于对象持久化实现爬虫现场快速还原
  2. 生成pfx文件需要在服务器上执行,PEM文件和private.key文件生成IIS服务器所需的pfx文件(配置SSL用)...
  3. 乐易家智能机器人价格_安川焊接机器人价格多少钱?核心是质量好
  4. python中删除字典中的某个元素_python怎样删除字典中的元素
  5. java切割文件_Java如何将大文件切割成小文件
  6. 思科扩展ACL具体怎么配置?
  7. CCNP实验【静态出接口配置】
  8. php怎么实现即时聊天,php实现socket即时通讯示例
  9. 阿里云消息队列 RocketMQ 5.0 全新升级:消息、事件、流融合处理平台
  10. 低成本运行 Spark 数据计算