Mongodb利用aggregation實現抽樣查詢(按記錄數和時間)


  之前對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 );

  

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM