Mongodb利用aggregation实现抽样查询(按记录数和时间)
2018-02-07 12:59
645 查看
之前对mongodb不熟,但是项目要用,因为数据量比较大,并且领导要实现抽样查询,控制数据流量,所以自己研究了下,亲测可用,分享一下!
话不多说,上代码:
第一种方案:加自增主键,实现按记录数抽样
1、记录在存入数据库时不适用默认id,改为自增id,具体实现如下:
2、查询数据,具体实现如下:
在demo中可以查询到按paramName为"aaa",retrieveTime为一天前至今,并且id值除以2余数为0的所有记录,更改除数的大小便实现了不同粒度的抽样查询。
第二种方案:借助 date aggragation ,实现按时间查询
前提是被查询数据中有字段为iso date类型retrieveTime,然后在aggregation中加入一个这样的MatchOperation,最后加入到Aggregation.newAggregation()即可实现查询分钟数为0,15,30,45的记录,同时支持的其它操作还有hour、seconds等。
话不多说,上代码:
第一种方案:加自增主键,实现按记录数抽样
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 );
相关文章推荐
- Java实现查询记录的时间相对于当前时间
- 利用标准SQL语句实现查询记录分页
- dubbo服务使用spring-data-mongodb进行时间查询的bug记录
- 急!查询所有用户两次登录的时间间隔小于5分钟的所有记录,能用自连接实现吗?
- 利用timestamp实现数据库处理同一记录的时间差异问题
- java Web项目中,利用其过滤功能,实现访问者每次访问服务器时,记录访问者的IP,访问时间,Url等信息,并保存到文件的操作
- 利用标准的SQL语句实现查询记录分页
- MongoDB利用正则表达式查询(pymongo实现)
- 利用timestamp实现数据库处理同一记录的时间差异问题
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。
- MySQL利用正则匹配函数实现多个条件查询
- MS SQL Server带有时间的记录怎样查询
- 利用回调技术实现的一个JDBC 查询操作(可依此进行扩展)
- 在php7中MongoDB实现模糊查询的方法详解
- 利用MySQL的一个特性实现MySQL查询结果的分页显示
- 利用C#实现分布式数据库查询(转载)
- 利用MySQL的函数实现PHP中时间的格式化输出
- 利用excel的数据有效性记录不随系统时间变化的时间
- 以字符串存储的时间值,如何实现你想要的格式查询出来
- 《利用条件随机场实现中文病历文本中时间关系的自动提取》——阅读笔记