因业务需要,需要在mongodb操作数据,mongodb数据格式为带数组array的文档行,现有需求如下:
查询数组中半年或者一年不活跃的数据和活跃的数据(以时间小于多少为准),大量查官方文档,民间野文后终解决问题。
思路为:
半年之内的为活跃数据,半年以前的为不活跃数据,不活跃数据为数组中所有元素的对应值都超过半年,但mongodb查询默认任一元素对应值匹配条件就算查询到,现解决数组内任一元素对应值不满足就放弃整个文档行问题。
数据格式:
{ "_id" : ObjectId("5fc4646a2b7bfb044c042e52"), "UNISCID" : 1, "ACTIVESTATELIST" : [ { "createTime" : "2022-02-09 00:00:00.000", "state" : 2 }, { "createTime" : "2022-02-09 00:00:00.000", "state" : 5 }, { "createTime" : "2022-02-09 00:00:00.000", "state" : 1 } ] } { "_id" : ObjectId("5fc4646a2b7bfb044c042e53"), "UNISCID" : 2, "ACTIVESTATELIST" : [ { "createTime" : "2021-08-09 00:00:00.000", "state" : 2 }, { "createTime" : "2021-08-09 00:00:00.000", "state" : 4 }, { "createTime" : "2021-08-09 00:00:00.000", "state" : 1 } ] }
1.活跃数据
db.getCollection("文档名").find({"ACTIVESTATELIST.createTime" : { $gte : ISODate("2022-02-09 00:00:00.000") }}).limit(1000).skip(0) java: Query query = new Query(); Criteria c = new Criteria(); c.and(ACTIVESTATELIST_CREATETIME).gte(LocalDateTime.now().minusMonths(6)); query.addCriteria(c); long count = mongoTemplate.count(query, "文档名");
2.半年/一年不活跃数据(核心思想:两次否定得出肯定,首先筛选出数组中所有数据的createTime都大于半年前的,然后取反即可。若是具体的字段就用$nin,这里还有DISTRICT和ENTERPRISETYPE两个条件)
db.getCollection("ENTERPRISE_LIVENESS_MODEL").find({ "DISTRICT": { "$regex": "510101.*", "$options": "" }, "ENTERPRISETYPE": "0", "ACTIVESTATELIST": { "$not": { "$elemMatch": { "createTime": { "$gte": { "$date": 1628494391512 } } } } } }) java: Query query = new Query(); Criteria c = new Criteria(); c.and(DISTRICT).regex(district + ".*"); c.and("ENTERPRISETYPE").is("0"); //半年 c.and("ACTIVESTATELIST").not().elemMatch(Criteria.where("createTime").gte(LocalDateTime.now().minusMonths(6))); //一年 c.and("ACTIVESTATELIST").not().elemMatch(Criteria.where("createTime").gte(LocalDateTime.now().minusMonths(12))); query.addCriteria(c); long count = mongoTemplate.count(query, "文档名");
注:查出来后半年前的数据会包含一年前的数据,而不是一年前包含半年前数据,如不想包含可再附上限制条件。