1.首先自定义一个查询的Operation

package com.pica.wx.bean;import com.mongodb.DBObject;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;/*** @author lqx* @create 2018-09-01 10:41*/public class CustomAggregationOperation  implements AggregationOperation {private DBObject operation;public CustomAggregationOperation (DBObject operation) {this.operation = operation;}public DBObject toDBObject(AggregationOperationContext context) {return context.getMappedObject(operation);}}

关联表查询如下

/*** 获取表单数据* @param isZYD 是不是志愿单页面0不是1是* @param ksmc* @param year* @param kaoshengksposition* @param kspositionrange* @param baowenchong* @param cbatch* @param yxdm* @param yxmc* @param currentPage* @param pageSize* @param sort_column* @param sort_direction* @param map* @param tag* @param city* @return* @throws Exception*/public Map<String,Object> findSchoolBWC(Integer isZYD,String ksmc, int year, int kaoshengksposition, int kspositionrange, String baowenchong, String cbatch,String yxdm, String yxmc, int currentPage, int pageSize, String sort_column, String sort_direction, Map<String, Object> map,String tag,String city)throws Exception {kspositionrange=kspositionrange*kaoshengksposition/100;map.put("result", true);List<AggregationOperation> operations=new ArrayList<AggregationOperation>();//添加年份条件operations.add(Aggregation.match(Criteria.where("year").is(year)));//关联school表获取city和tagoperations.add(new CustomAggregationOperation(new BasicDBObject("$lookup",new BasicDBObject("from", "schools").append("localField","yxmc").append("foreignField", "name").append("as", "schools"))));//添加批次条件operations.add(Aggregation.match(Criteria.where("cbatch").is(cbatch)));//添加科目条件operations.add(Aggregation.match(Criteria.where("ksmc").is(ksmc)));//添加排序operations.add(Aggregation.sort(new Sort(new Sort.Order(sort_direction.toLowerCase().equals("desc") ? Direction.DESC:Direction.ASC,sort_column))));//添加城市条件if(StringUtils.isNotBlank(city)){operations.add(Aggregation.match(Criteria.where("schools.cityname").is(city)));}//添加tag条件if(StringUtils.isNotBlank(tag)){operations.add(Aggregation.match(Criteria.where("schools.tags").regex(tag)));}int count=0;//总数List<Map> raws=new ArrayList<Map>();int baoTotalPage=0;//bao总页数int wenTotalPage=0;//wen总页数int chongTotalPage=0;//chong总页数//控制显示字段if (baowenchong.toLowerCase().equals("bao")||isZYD==1) {//创建bao查询集合List<AggregationOperation> baoOperations=new ArrayList<AggregationOperation>();baoOperations.addAll(operations);baoOperations.add(Aggregation.match(Criteria.where("fmaxksposition").gte(kaoshengksposition +kspositionrange)));//获取总数List<AggregationOperation> countOperations=new ArrayList<AggregationOperation>();countOperations.addAll(baoOperations);int baoCount=getTotalCount(countOperations);count+=baoCount;baoTotalPage=(baoCount + pageSize  -1) / pageSize;//添加分页并获取结果集//获取要显示的字段baoOperations.add(getBaseShowFiled("bao"));List<Map> baoRaws=addPageInfoAndGetResult(baoOperations,currentPage,pageSize);raws.addAll(baoRaws);}if(baowenchong.toLowerCase().equals("wen")||isZYD==1){//创建wen查询集合List<AggregationOperation> wenOperations=new ArrayList<AggregationOperation>();wenOperations.addAll(operations);wenOperations.add(Aggregation.match(Criteria.where("fmaxksposition").lte(kaoshengksposition-kspositionrange)));wenOperations.add(Aggregation.match(Criteria.where("fminksposition").gte(kaoshengksposition+kspositionrange)));//获取总数List<AggregationOperation> countOperations=new ArrayList<AggregationOperation>();countOperations.addAll(wenOperations);int wenCount=getTotalCount(countOperations);count+=wenCount;wenTotalPage=(wenCount + pageSize  -1) / pageSize;//添加分页并获取结果集//获取要显示的字段CustomAggregationOperation projectOperation=getBaseShowFiled("wen");wenOperations.add(projectOperation);List<Map> wenRaws=addPageInfoAndGetResult(wenOperations,currentPage,pageSize);raws.addAll(wenRaws);}if(baowenchong.toLowerCase().equals("chong")||isZYD==1){//创建chong查询集合List<AggregationOperation> chongOperations=new ArrayList<AggregationOperation>();chongOperations.addAll(operations);chongOperations.add(Aggregation.match(Criteria.where("fminksposition").lte(kaoshengksposition-kspositionrange)));//获取总数List<AggregationOperation> countOperations=new ArrayList<AggregationOperation>();countOperations.addAll(chongOperations);int chongCount=getTotalCount(countOperations);count+=chongCount;chongTotalPage=(chongCount + pageSize  -1) / pageSize;//添加分页并获取结果集//获取要显示的字段chongOperations.add(getBaseShowFiled("chong"));List<Map> chongRaws=addPageInfoAndGetResult(chongOperations,currentPage,pageSize);raws.addAll(chongRaws);}Page page=new Page();page.setCurrentPage(currentPage);page.setPageSize(pageSize);//初始化数组List<Integer> totalPages = new ArrayList<Integer>();totalPages.add(baoTotalPage);totalPages.add(wenTotalPage);totalPages.add(chongTotalPage);//获取最大页数作为总页数page.setTotalPage(Collections.max(totalPages));page.setRows(raws);page.setTotalCount(count);map.put("data", page);//获取往年情况if(page.getRows()!=null&&page.getRows().size()>0){chanWangNianLQQK(map,page,ksmc,year,cbatch,kaoshengksposition);}return map;}

3.如果要添加自定义字段,上面方法中用到的方法如下

 /*** 获取要显示的字段* @param baowenchong* @return*/public CustomAggregationOperation getBaseShowFiled(String baowenchong){CustomAggregationOperation projectOperation=new CustomAggregationOperation(new BasicDBObject("$project",new BasicDBObject("year", 1).append("yxmc",1).append("ksmcname", 1).append("cbatch", 1).append("cbatchname", 1).append("yxdm", 1).append("yxmc", 1).append("plan", 1).append("planenrollment", 1).append("enrollment", 1).append("fmax", 1).append("fmin", 1).append("favg", 1).append("fmaxksposition", 1).append("fminksposition", 1).append("yxsf", 1).append("yxtag", 1).append("schools", 1).append("baowenchong", baowenchong)));return projectOperation;}/*** 添加分页并获取结果集* @param operations* @param currentPage* @param pageSize* @return*/public List<Map> addPageInfoAndGetResult(List<AggregationOperation> operations,Integer currentPage,Integer pageSize){operations.add(Aggregation.skip((long)((currentPage-1)*pageSize)));operations.add(Aggregation.limit((long)pageSize));Aggregation aggregation =  Aggregation.newAggregation(operations);AggregationResults<Map> aggRes = mongoTemplate.aggregate(aggregation,"ptyxzslqtjb", Map.class);List<Map> raws=aggRes.getMappedResults();return raws;}/*** 获取总数* @param countOperations* @return*/public int getTotalCount(List<AggregationOperation> countOperations){int count=0;countOperations.add(Aggregation.group().count().as("count"));Aggregation countaggregation =  Aggregation.newAggregation(countOperations);AggregationResults<Map> countRes = mongoTemplate.aggregate(countaggregation, "ptyxzslqtjb", Map.class);List<Map> coutMapRes = countRes.getMappedResults();if(coutMapRes!=null&&coutMapRes.size()>0){count =  (Integer)coutMapRes.get(0).get("count");}return count;}

4.数组查询方法

对数组根据条件查询

 $all、$size、$slice、$elemMatch

(1)$all查找数组中包含指定的值的文档

语法:

{ field:{ $all: [ <value> , <value1> ... ]}

例子:

db.orders.find({"books":{$all:["java","mongo"]}})

查找books包含java、mongo的文档数据

(2)$size 查找数组大小等于指定值的文档

语法:

   {field: {$size: number } }

例子:

          >db.orders.find({"books":{$size:2}})

(3)$slice查询数组中指定返回元素的个数

语法:

         >db.collect.find({},{field:{$slice: number }})

number 说明:

为正数表示返回前面指定的值的个数:例如1 返回数组第一个

为负数表示返回倒数指定的值的个数:例如-1返回数组倒数第一个

例子:

        >db.orders.find({"onumber":{$in:["008","009"]}},{books:{$slice:1}})

   1)$slice可以查询数组中第几个到第几个

语法:

            >db.collect.find({},{field:{$slice:[ number1, number2] }})

跳过数组的number1个位置然后返回number2个数

number1说明:

为正数表示跳到指定值的数组个数:例如2 跳到数组第3个

为负数表示跳到指定值的数组倒数个数:例如-2跳到到数组倒数第3个

例子:

           >db.orders.find({"onumber":{$in:["008","009"]}},{books:{$slice:[1,1]}})

跳过books数组第一个元素,现在到数组第二个元素,并返回1个元素

三、对数组内嵌文档查询

我们先保存数据

  1. <span style="font-size:18px;">

  2. db. orders.insert([

  3. {

  4. "onumber" : "001",

  5. "date" : "2015-07-02",

  6. "cname" : "zcy1",

  7. "items" :[ {

  8. "ino" : "001",

  9. "quantity" :2,

  10. "price" : 4.0

  11. },{

  12. "ino" : "002",

  13. "quantity" : 4,

  14. "price" : 6.0

  15. }

  16. ]

  17. },{

  18. "onumber" : "002",

  19. "date" : "2015-07-02",

  20. "cname" : "zcy2",

  21. "items" :[ {

  22. "ino" : "001",

  23. "quantity" :2,

  24. "price" : 4.0

  25. },{

  26. "ino" : "002",

  27. "quantity" :6,

  28. "price" : 6.0

  29. }

  30. ]

  31. }

  32. ])</span>

(1)$elemMatch 文档包含有一个元素是数组,那么$elemMatch可以匹配内数组内的元素并返回文档数据

语法:

         >{field:{$elemMatch:{ field1:value1, field2:value2,………}}}

例子:

         >db.orders.find({"items":{$elemMatch:{"quantity":2}}})

返回quantity为2的文档

也可以这样查询db.orders.find({"items.quantity":2})

(2) $elemMatch可以带多个查询条件

例子:

      >db.orders.find({"items":{$elemMatch:{"quantity":4,"ino":"002"}}})

我们查询数组中的quantity等于4并且ino等于002,但是我们就想返回数组中的quantity等于4并且ino等于002的这个文档,并不想把ino等于001等这些无关的文档返回。

(3)$elemMatch 同样可以用在find方法的第二个参数来限制返回数组内的元素,只返回我们需要的文档

例子:

db.orders.find({"onumber":"001"},{"items":{$elemMatch:{"quantity":4,"ino":"002"}},"cname":1,"date":1,"onumber":1})

 我们只返回quantity等于4并且ino等于002的文档,无关的文档没有返回,方便我们处理数据,这样也可以节省传输数据量,减少了内存消耗,提高了性能,在数据大时,性能很明显的。

mongodb关联表查询相关推荐

  1. MongoDB联表查询aggregate : $lookup

    参考:MongoDB联表查询 建表插入数据: db.createCollection("user") db.user.insertMany([{_id: ObjectId(&quo ...

  2. Mybatis源码分析--关联表查询及延迟加载原理(二)

    在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...

  3. Mybatis实现关联表查询

    Mybatis实现关联表查询 6.1. 一对一关联 1). 提出需求 根据班级 id 查询班级信息(带老师的信息) 2). 创建表和数据 [](javascript:void(0)

  4. MySQL 实现多张无关联表查询数据并分页

    MySQL 实现多张无关联表查询数据并分页 1.功能需求 在三张没有主外键关联的表中取出自己想要的数据,并且分页. 2.数据库表结构 水果表: 坚果表: 饮料表: 主要用UNION AL UNION ...

  5. hibernate mysql 关联查询_hibernate 查询缓存,以及在关联表查询缓存下使用HQL,而不是sql去查询...

    什么是查询缓存? 也就是如果开启了查询缓存, 在 没有使用二级缓存的情况下,会 缓存第一次查询出来的数据的id. 第二次查询的时候, 如果查询的参数和查询语句没有变化,那么就会使用 第一次查询的出来的 ...

  6. MyBatis学习总结(五)——实现关联表查询

    2019独角兽企业重金招聘Python工程师标准>>> 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里 ...

  7. MyBatis学习总结(5)——实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  8. Mybatis系列(三):Mybatis实现关联表查询

    原文链接:http://www.cnblogs.com/xdp-gacl/p/4264440.html 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 ...

  9. $lookup做关联表查询

    两张表格answer和question. #------------------------------------------------------------------------------ ...

最新文章

  1. 强化学习Reinforcement Learning
  2. NVIDIA之AI Course:Getting Started with AI on Jetson Nano—Class notes(一)
  3. what is ssao
  4. WebSocket使用,包括服务端和客户端(JAVA实现)
  5. java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)
  6. linux系统之上搭建maven 之nexus服务篇
  7. 遇到没有exe文件的驱动
  8. c++ 二次开发 良田高拍仪_捷易拍sdk开发指南(高拍仪、文件拍摄仪二次开发软件)...
  9. 老年人计算机培训方案,老年人学电脑从新手到高手
  10. java openoffic linux_Linux操作系统下安装Openoffice3.2
  11. gta5 android ps4,gta5导演模式怎么玩好玩_gta5怎么进入导演模式怎么玩ps4导演模式怎么打开_攻略...
  12. 【PyTorch深度学习项目实战100例】—— 基于CNN实现书法字体风格识别任务 | 第62例
  13. 什么是 5G CPE
  14. python 读取doc 和 docx
  15. pytorch系统学习
  16. 中科大计算机科学夏令营,2019中科大计算机夏令营机试
  17. 网络传输中的数据长度
  18. 删除临时文件夹中的特定名称模式目录
  19. 社区无人便利店APP开发解决方案
  20. 【Android控件属性记录】

热门文章

  1. 华为机试真题 Java 实现【数字涂色】
  2. ios-swift imgview 加载网络图片
  3. ubuntu DNS修改
  4. UVa 10387 Billiard
  5. CSS3实现渐变背景动画特效
  6. 项目开发过程中的管理规范
  7. 移动软件开发-设计app首页
  8. 本地项目的一个git仓库损坏如何恢复
  9. svn修改offline状态
  10. 程序员转正述职报告_程序员个人转正述职报告