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语句
三:spring-data-mongodb与mongo shell的对应关系
spring-data-mongodb与mongo shell的对应关系的更多相关文章
- Spring Data MongoDB example with Spring MVC 3.2
Spring Data MongoDB example with Spring MVC 3.2 Here is another example web application built with S ...
- 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南
1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...
- Spring data mongodb 聚合,投射,内嵌数组文档分页.
尽量别直接用 DBObject ,Spring data mongodb 的api 本来就没什么多大用处,如果还直接用 DBObject 那么还需要自己去解析结果,说动做个对象映射,累不累 Spri ...
- Spring data mongodb @CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy SpringSecurityAuditorAware,只记录用户名
要在Spring data mongodb 中使用@CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy 这四个注解 必须实现 SpringSecuri ...
- Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)
一.简单介绍 Spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一 ...
- Introduction to Spring Data MongoDB
Introduction to Spring Data MongoDB I just announced the new Spring 5 modules in REST With Spring: & ...
- Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)
一.简介 Spring Data MongoDB 项目提供与MongoDB文档数据库的集成.Spring Data MongoDB POJO的关键功能区域为中心的模型与MongoDB的DBColle ...
- Spring Data MongoDB 三:基本文档查询(Query、BasicQuery
一.简介 spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我 ...
- Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)
Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 六: MongoDB查询(游标操作.游标信息)(三) 一.简单介绍 Spring ...
随机推荐
- winform使用log4.net
因为我最近负责的Winform项目,好多都用到了这个log4net的日志功能,开发程序对数据一般都要求做到雁过留痕,所以日志对于我们程序员是不可或缺.因此我把对log4net的使用做一个记录总结,以便 ...
- Java JDK下载、安装和验证
1.JDK下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html,点开链接看到如下图所示的界面: 2.点击上图 ...
- leecode第二百三十一题(2的幂)
class Solution { public: bool isPowerOfTwo(int n) { bool is_flag=false; ) { ==)//如果为1,看是不是第一个1 { if( ...
- Springboot 中配置文件的优先级和加载顺序
1. 若application.yml 和bootStrap.yml 在同一目录下,则bootStrap.yml 的加载顺序要高于application.yml,即bootStrap.yml 会优先 ...
- 超详细的java集合讲解
1 集合 1.1 为什么会出现集合框架 [1] 之前的数组作为容器时,不能自动拓容 [2] 数值在进行添加和删除操作时,需要开发者自己实现添加和删除. 1.2 Collection接口 1.2.1 C ...
- Oracle解决ora-01653 无法通过1024扩展
综合上述检查结果,可断定遇到的问题是因为可能性1—表空间不足导致.解决办法也就是扩大表空间 扩大表空间的四种方法: 1.增加数据文件 ALTER TABLESPACE ***_TRD ADD DATA ...
- 非阻塞tcp服务器与阻塞的tcp服务器对比
一般的tcp服务器(阻塞)是使用的如下 [erlang] gen_tcp传输文件原型 http://www.cnblogs.com/bluefrog/archive/2012/09/10/267904 ...
- vue部署的路径问题
本人在开始学习vue的过程中,虽然比较容易上手,还是碰到了很多坑,比如我今天要说的VUE的部署问题.我在部署vue的过程中发现自己在开发环境中,页面什么都可以跑起来,但是npm dev build后发 ...
- 解决ajax跨域
今天要联调项目,前后端请求使用ajax,联调存在跨域问题,解决办法如下: (1)在本地的电脑上新建一个文件夹,用于前后端联调存放浏览器 缓存的 (2)打开桌面的谷歌浏览器图标(右键>属性> ...
- git 拉取远程代码
git 拉取远程代码 || 利用vscode编辑器自带了git,可在ctrl+~打开控制台拉取代码,非常好用哦~在实际项目开发过程中,往往是已经存在远程项目了,我们定义的需求是只需要简单的操作git, ...