网站首页 > 基础教程 正文
之前对于spring的mongoTemplate真的是有点又爱又恨,由于它对mongodb的驱动做了一层封装,使得在开发的时候方便了许多,但是它的语法和mongo的原生js有很大不同,有时候在mongo官方文档里的API接口很多时候在mongoTemplate中的使用完全不一样,导致有些时候用的很别扭,而且一些语句完全不知道怎么去转换为template的语法。不过最近的两次使用经历使得我对mongoTemplate有了一些改观。
第一个就是mongoTemplate自身的criteria.where没有>和<的操作,也就是对mongo的一条记录自身的两个字段进行比较。mongo语句如下:
db.whereColl.find({$where: "this.b > this.a"})
当时研究和许久,最后实在没招了,扒源码找出了它的Criteria实现,下面是它的源码实现:
/**
/**
private BasicDBList createCriteriaList(Criteria[] criteria) {
public DBObject getCriteriaObject() {
protected DBObject getSingleCriteriaObject() {
private void setValue(DBObject dbo, String key, Object value) {
通过上面的源码可以知道,mongoTemplate的语法转换是通过构建一个DBObject,然后将查询语法转换为mongo的Java驱动的语法,也是接近于原生的语法。
知道了这个,稍微对com.mongodb包有些经验的都应该知道要怎么去操作了,我们通过复写getCriteriaObject方法来实现自定义查询语句,突破mongoTemplate的限制,我的实现如下:
public ListResponse<AObject> loadAObjectList(String aId, String bId, int start, int limit) { ListResponse<AObject> AObjectListResp = new ListResponse<AObject>(); Criteria criteria = new Criteria() { @Override public DBObject getCriteriaObject() { DBObject obj = new BasicDBObject(); obj.put("$where", "this.groupNum > this.joinedNum"); return obj; } }; Query query = Query.query(criteria); query.addCriteria(Criteria.where("members").nin(bId).and("aId").is(aId)).with(new Sort(Sort.Direction.DESC, "gmtCreated")).skip((start-1) * limit).limit(limit); List<AObject> AObjectList = template.find(query, AObject.class); long count = template.count(new Query(criteria).addCriteria(.where("members").nin(bId).and("aId").is(aId)), AObject.class); return AObjectListResp.fill(ResponseCode.SUCCESS, "success", AObjectList, count, count > start * limit);
上面我们通过复写相关方法来自定义Criteria语法,而另一个事件是今天的一个项目,需要从mongo中随机取出一定数量的文档,我们知道mongo在3.2版本之后对此加入了一个官方的api,我们可以使用aggregate管道的$sample来读取文件,mongo语法如下:
db.users.aggregate(
我看了mongotemple的aggregate相关API,发现它的API只有以下几个,即便是升级到最新的1.10.0-RELEASE版本也是如此,最后我想起上面的自定义扩展,于是,又去吭哧吭哧地翻看源代码,首先:
template.aggregate(Aggregation.newAggregation(Aggregation.match(Criteria),.....),....);
我发现它的语法条件都是通过Aggregation.XXX来操作的,于是,我打开Aggregation.XXX的源码:
/**
/**
我发现它是构建不同的XXXOperation,于是,我打开MatchOperation和LimitOperation:
public class MatchOperation implements AggregationOperation {
public class LimitOperation implements AggregationOperation {
到这儿,我发现最终,它的操作也是落到了BasicDBObject上面,并且都是通过继承AggregationOperation来实现的,于是我照着葫芦画瓢,自己自定义了一个SampleOperation类:
public class SampleOperation implements AggregationOperation {
通过这两次经历,我发现mongoTemplate虽然语法上和原生的语法有些不同之处,但是它在设计之初充分地考虑到了开发的自定义扩展。
上面是我个人的一些小小的心(惨)得(通)经(教)验(训),希望能够对大家有些帮助。
猜你喜欢
- 2024-10-29 57个挑战之57(part6):客户端+web前端+服务端代码实现
- 2024-10-29 技术干货|MongoDB数据库常见操作命令
- 2024-10-29 ABP vNext框架文档解读28-数据过滤
- 2024-10-29 自建MongoDB实践:MongoDB 分片集群
- 2024-10-29 小程序 随机读取数据并生成分享图片 上手笔记
- 2024-10-29 go-mongox:简单高效,让文档操作和 bson 数据构造更流畅
- 2024-10-29 当MongoDB遇见Spark mongodb campass
- 2024-10-29 MongoDB 5.0 官方文档学习笔记 mongodb教程
- 2024-10-29 好东西,MySQL 数据库 MongoDB详解
- 2024-10-29 MongoDB 入门 day04 mongodb27017
- 最近发表
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- mysql教程 (60)
- pythonif (86)
- location.href (69)
- deletesql (62)
- c++模板 (62)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)