之前对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. 编写高质量代码改善C#程序的157个建议——建议103:区分组合和继承的应用场合

    建议103:区分组合和继承的应用场合 继承所带来的多态性虽然是面向对象的一个重要特性,但这种特性不能在所有的场合中滥用.继承应该被当做设计架构的有用补充,而不是全部. 组合不能用于多态,但组合使用的频 ...

  2. MVC4 基于 Unity Ioc 框架的 ControllerFactory

    首先引入Untiy框架. 可以在NuGet程序包 管理器中直接安装. 新建 继承DefaultControllerFactory  的UnityControllerFactory: 重写虚方法GetC ...

  3. Windows store app[Part 4]:深入WinRT的异步机制

    接上篇Windows store app[Part 3]:认识WinRT的异步机制 WinRT异步机制回顾: IAsyncInfo接口:WinRT下异步功能的核心,该接口提供所有异步操作的基本功能,如 ...

  4. openedx使用中可能用到的一些资源

    这几天一直在弄openedx,你会发现安装好只是第一步,后面还有很多东西在等着你,那么哪里可以看到较新的资料了,分享几个站点: 1.https://readthedocs.org/projects/e ...

  5. ODBC方式操作oracle数据库

    ODBC方式操作oracle数据库 一.查询语句: var strConn = System.Configuration.ConfigurationManager.ConnectionStrings[ ...

  6. Jquery中each

    1.选择器+遍历 $('div').each(function (i){ i就是索引值 this 表示获取遍历每一个dom对象 }); 2.选择器+遍历 $('div').each(function  ...

  7. “全栈2019”Java第四十七章:继承与方法

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. kali linux之Meterpreter

    高级,动态,可扩展的payload 基于meterpreter上下文利用更多漏洞发起攻击,后渗透阶段一站式操作界面 完全基于内存的dll注入式payload(不写硬盘) 注入合法系统进程并建立stag ...

  9. jvisualvm_使用jmx连接远程linux应用

    [前提] JVisualVM是由Sun提供的性能分析工具,在Jdk6.0以后的版本中是自带的,如果是用Jdk1.5或以前版本的就得要单独安装了. [1]远程机器需要开启jmx 在使用jvisualvm ...

  10. TCP的坚持定时器

    一.简介 TCP不对ACK报文段进行确认,TCP只确认那些包含有数据的ACK字段. 如果一个确认丢失了,双方就有可能因为等待对方而使得链连接终止: 接收方等待接受数据,因为已经向发送方通告了一个非0的 ...