之前对mongodb不熟,但是项目要用,因为数据量比较大,并且领导要实现抽样查询,控制数据流量,所以自己研究了下,亲测可用,分享一下!

  话不多说,上代码:

  第一种方案:加自增主键,实现按记录数抽样  

  1、记录在存入数据库时不适用默认id,改为自增id,具体实现如下:

  

/**
* 序列类,用于映射查询的序列值
* @author Administrator
*
*/
public class MongoSequence {
@Id
private String id;
private int seq; }

  

/**
* 获取序列号工具类
* @author Administrator
*
*/
@Component
public class MongoAutoidUtil { @Autowired
MongoTemplate mongoTemplate; public int getNextSequence(String collectionName) {
Query query = new Query(Criteria.where("collName").is(collectionName));
Update update = new Update();
update.inc("seq", 1);
FindAndModifyOptions options = new FindAndModifyOptions();
options.upsert(true);
options.returnNew(true);
MongoSequence seqId = mongoTemplate.findAndModify(query, update, options, MongoSequence.class);
return seqId.getSeq(); } }
//插入数据
public void insert(DeviceData110 de) {
de.setId(mongoAutoidUtil.getNextSequence(de.getParamName()));
mongoTemplate.save(de,de.getParamName());
}

  2、查询数据,具体实现如下:

    @Autowired
private MongoTemplate mongoTemplate; public List<DeviceData110> find() {
ProjectionOperation dateProjection = Aggregation.project("_id","paramName","retrieveTime");
MatchOperation match1 = Aggregation.match(new Criteria("paramName").is("aaa"));
MatchOperation match2 = Aggregation.match(new Criteria("retrieveTime").gte(DateUtil.getAssignTime(new Date(), -1)).lte(DateUtil.getAssignTime(new Date(), 1)));
MatchOperation match3 = Aggregation.match(new Criteria("_id").mod(2, 0));
Aggregation agg = Aggregation.newAggregation(dateProjection,match1,match2,match3);
AggregationResults<DeviceData110> results = mongoTemplate.aggregate(agg,"aaa",DeviceData110.class);
List<DeviceData110> list = results.getMappedResults();
return list;
}

  

//实体类
public class DeviceData110 implements Serializable{ private static final long serialVersionUID = -4763630558724084819L;
public int id;
public String paramName;
public Date retrieveTime; }

  在demo中可以查询到按paramName为"aaa",retrieveTime为一天前至今,并且id值除以2余数为0的所有记录,更改除数的大小便实现了不同粒度的抽样查询。

  第二种方案:借助 date aggragation ,实现按时间查询

  前提是被查询数据中有字段为iso date类型retrieveTime,然后在aggregation中加入一个这样的MatchOperation,最后加入到Aggregation.newAggregation()即可实现查询分钟数为0,15,30,45的记录,同时支持的其它操作还有hour、seconds等。

ProjectionOperation project1 =  Aggregation.project("_id").andExpression("minute(retrieveTime)").as("minute"),
MatchOperation match = Aggregation.match(new Criteria("minute").in("0","15","30","45"));
Aggregation agg = Aggregation.newAggregation(project1 、match );

  

  

Mongodb利用aggregation实现抽样查询(按记录数和时间)的更多相关文章

  1. MySQL之单表查询 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER BY 八 限制查询的记录数:LIMIT 九 使用正则表达式查询

    MySQL之单表查询 阅读目录 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER B ...

  2. MongoDB(六):选择字段、限制记录数、排序记录

    1. 选择字段 在MongoDB中,选择字段又叫投影,表示仅选择所需要字段的数据,而不是选择整个文档字段的数据.如果某个文档有5个字段,但只要显示3个字段,那么就只选择3个字段吧,这样做是非常有好处的 ...

  3. 优化mybatis框架中的查询用户记录数的案例

    通过对mybatis框架的中核心接口和类的分析,发现之前写的那个小demo是有问题的.现在对其进行部分优化. 如果存在多个功能的时候,势必会有很多重复的代码,如,创建sqlsession对象,关闭sq ...

  4. mysql 数据操作 单表查询 limit 限制查询的记录数

    mysql; +----+-----------+------+-----+------------+---------+--------------+------------+--------+-- ...

  5. Hibernate查询总的记录数

    1. 原生sql String hql="select count(*) from product" ;//此处的product是数据库中的表名 Query query=sessi ...

  6. 使用传入的总记录数实现一条sql语句完成分页查询

    使用传入的总记录数实现一条sql语句完成分页查询     问题:在传统的分页查询的实现中不可避免的需要两条sql语句,一条用于查询数据一条用于查询总记录数.如下面的实际代码所示: Img1 当然如果使 ...

  7. Oracle查询数据库中所有表的记录数

    1.Oracle查询数据库中所有表的记录数,但是有可能不准建议用第二种方式进行查询 select t.table_name,t.num_rows from user_tables t 2.创建orac ...

  8. myBatis框架_关于怎么获得多表查询的总记录数

    <!-- 查找总记录数 --> <select id="billCount" resultType="int"> select coun ...

  9. mysql数据库补充知识2 查询数据库记录信息之单表查询

    一 单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键 ...

随机推荐

  1. SQL server 累加求和

    1. SELECT SalesOrderID, ProductID, OrderQty    ,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS Tot ...

  2. Android新增的注解

    环境 使用Android注解前需要导入相关的包 compile 'com.android.support:support-annotations:latest.integration' 注意:如果我们 ...

  3. Android Paint以及ColorFilter等

    我们可以通过Paint中大量的setter方法来为画笔设置属性: 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfe ...

  4. Maven整理笔记のMaven使用

    POM 就像Make的Makefile,Ant的build.xml一样,Maven项目的核心是pom.xml.POM(Project Object Model项目对象模型),定义了项目的基本信息,用于 ...

  5. C#中的线程

    1.线程Thread 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程 ...

  6. JAVA程序对MYSQL数据库加锁实验

    什么是脏读,不可重复读,幻读 1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重 ...

  7. 【RabbitMQ学习记录】- 消息队列存储机制源码分析

    本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...

  8. 二十、Node.js- WEB 服务器 (三)静态文件托管、 路 由

    1.Nodejs 静态文件托管 上一讲的静态 web 服务器封装 项目结构: Web服务器封装成的模块:router.js代码: var http=require('http'); var fs=re ...

  9. kvm虚拟机静态迁移

    1.静态迁移就是虚拟机在关机状态下,拷贝虚拟机虚拟磁盘文件与配置文件到目标虚拟主机中,实现的迁移. (1)虚拟主机各自使用本地存储存放虚拟机磁盘文件 本文实现基于本地磁盘存储虚拟机磁盘文件的迁移方式, ...

  10. leecode刷题(12)-- 整数反转

    leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...