java mongodb Aggregation复杂操作解决方案
问题背景
现在需要在查询mongodb,已经超时、已经不该存活并且需要进行操作的对象
目前我所想到的方法有如下几种:
- 使用最原始的方法(dsl、@Query或者springdata等等),然后再做比较时间/判断标记类型等等操作,这种逻辑在服务器做似乎有点消耗性能
- 使用mongo包里Aggregation原生的写法
- 使用springdata 提供的Aggregation.newAggregation() 写法
进化之路
刚开是的时候,第一种方法很明显不适合我们的做法,本来就是定时1~2秒去访问一次mongo,并把数据进行处理。这样就不能在服务端消耗太多的时间,直接pass。
第二种方法,废话少说直接上查询语句:
db.RefreshTask.aggregate([
{
$project: {
_id:1, uri:1, scope:1, desc:1, pushState:1,
collectState:1, collectInterval:1, lastCollectTime:1, refreshRequestHeaders:1,
effectivePercent:1, hasDataVersion:1, childTaskAlivePeriod:1, parentId:1, createdTime:1,
lastModifiedTime:1, lastCollectValue:1, lastPushValue:1, expireFlag:1, nextCollectTime:1,
expireTime:{
$add: [ "$createdTime", {
$multiply: [ "$childTaskAlivePeriod", 1000 ] } ]} }},
{
$match:{
$or:[{
expireFlag:{
$eq:true}},
{
$and:[{
collectState:{
$eq:1}}, {
nextCollectTime:{
$lt:ISODate()}}]},
{
expireTime:{
$lt:ISODate()}}]}}
]
)
好的,刚刚接触的同学肯定已经懵了。这什么鬼!一层层复杂的嵌套。如果找一个大腿,他可能会告诉你,去看官文吧:https://docs.mongodb.com/manual/reference/operator/aggregation/ 没毛病!
但是,我经过一下段时间研究,代码发现好像还是挺简单的,用方法2-mongo官方提供的包做的话,写代码也就层层嵌套就完事了。比如下面这样:
Date now = new Date();
DBCollection dbCollection = mongodb.getCollection("RefreshTask");
// $project
BasicDBList addList = new BasicDBList();
BasicDBList multiplyList = new BasicDBList();
multiplyList.add("$childTaskAlivePeriod");
multiplyList.add(1000);
BasicDBObject $multiply = new BasicDBObject("$multiply", multiplyList);
addList.add("$createdTime");
addList.add($multiply);
BasicDBObject $