mongodb java bson格式 根据指定条件查询、去重、排序

今天接收到一个新的接口需求:

1、获取24小时内最近的2条信息,生成这样的json格式

  

[-{
	"report_time": "20180705000000",
	-"forecast": [-{
		"forecast_time": "20180705000000"
	}, -{
		"forecast_time": "20180706030000"
	}]
}, -{
	"report_time": "20180704120000",
	-"forecast": [-{
		"forecast_time": "20180704120000"
	}, -{
		"forecast_time": "20180704150000"
	}]
}]

mongoDB数据库数据格式:

{
        "shortName": "~",
        "report_time": "20180704120000",
        "forecast_time": "20180704120000",
        "level": NumberInt("850"),
        "startLatitude": 60.0,
        "startLongitude": 60.0,
        "endLatitude": -10.0,
        "endLongitude": 150.0,
        "index": NumberInt("0"),
        "path": "/*************************************"
    },
{
        "shortName": "~",
        "report_time": "20180704120000",
        "forecast_time": "20180704150000",
        "level": NumberInt("850"),
        "startLatitude": 60.0,
        "startLongitude": 60.0,
        "endLatitude": -10.0,
        "endLongitude": 150.0,
        "index": NumberInt("0"),
        "path": "/*************************************"
    }

分析需求:可以分为3步:

1、查询24小时内数据

2、对该数据进行的report_time 进行进行去重排序

3、根据去过重的report_time获取forecast_time,然后对forecast_time进行去重、排序


提到去重,于是想到了两种方法:

1、通过mongodb提供的distinct方法去重

2、通过需要去重的字段分组就可以去重

--------------------------------------------------------------------------------------------------------------------------------

1、mongodb提供的distinct方法

	public DistinctIterable<String> distinctData(String tableName,String fieldName,Bson query,Class<String> resultClass) {
		collection = mongoDatabase.getCollection(tableName);
		
	    return	collection.distinct(fieldName,query, resultClass);
	}
	

真正用的时候发现,发现distinct方法没有提供排序功能,准备手动排序,但是发现DistinctIterable类型只能通过迭代器或者foreach遍历,要想排序还得把其中的数据遍历到数组或者集合,然后排序,想到需要多次遍历感觉可不爽。

----------------------------------------------------------------------------------------------------------------------------------

2、通过需要去重的字段分组就可以去重。

    分组的话知道mongodb提供了聚合函数Aggregates,于是开始查询Aggregates资料,发现网上都是用的mongodb提供的DBobject数据格式来操作Aggregates的,但是我这儿用的Bson格式的数据格式,本想的这俩应该差不多,按照DBobjct格式去处理,发现不行,只好查API了,最后发现只需要把自己需要查询的条件放入聚合管道就可以了,具体方法如下:

              1、获取集合

	/**
	 * 用聚合函数筛选数据
	 * @param list 聚合条件
	 * @return 
	 */
	public AggregateIterable<Document> findByAggregate(String tableName,List<Bson> list) {
		collection = mongoDatabase.getCollection(tableName);
		
		return  collection.aggregate(list);
	}

             2、按照条件操作

           

	/**
	 *
	 * 
	 * @param tableName  集合名称
	 * @return
	 */
	public String getNearByReportTime(String windTableName) {

		JSONArray array = new JSONArray();
		Calendar cal = Calendar.getInstance();

		cal.add(Calendar.HOUR_OF_DAY, -32);
		String date = String.format("%04d%02d%02d%02d0000", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
				cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY));
 
		AggregateIterable<Document> reportTimeList =	 repository.findByAggregate(windTableName, Arrays.asList(Aggregates.match(Filters.gte("report_time", date)), //查询24小时内数据
					Aggregates.sort(Filters.eq("report_time", 1)),  //数据按照 report_time 排序
					Aggregates.group("$report_time",new BsonField[] { new BsonField("report_time", Filters.eq("$first", "$report_time"))}), //按照report_time分组,并且,获取分组以后的第一个document中report_time的值
					 Aggregates.project(Filters.eq("_id", 0)), //查询结果不需要_id 这个字段
					 Aggregates.limit(2)  //只要最近的两条数据
					)				   
				 );
      
		for (Document document : reportTimeList) {
		   JSONObject obj = new JSONObject();
		   String report_time = document.getString("report_time");
		   obj.put("report_time", report_time);
		   AggregateIterable<Document> temp = repository.findByAggregate(windTableName, 
				   Arrays.asList(Aggregates.match(Filters.eq("report_time", report_time)),
							
							Aggregates.group("$forecast_time",new BsonField[] { new BsonField("forecast_time", Filters.eq("$first", "$forecast_time"))}),
							 Aggregates.project(Filters.eq("_id", 0)),
							 Aggregates.sort(Filters.eq("forecast_time", 1))
							)				   
				   );
		   obj.put("forecast", temp);
		   array.add(obj);
		   
		}
		
	       return array.toJSONString();
	}

查询结果:

[-{
	"report_time": "20180705000000",
	-"forecast": [-{
		"forecast_time": "20180705000000"
	}, -{
		"forecast_time": "20180706030000"
	}, -{
		"forecast_time": "20180714000000"
	}, -{
		"forecast_time": "20180714060000"
	}]
}, -{
	"report_time": "20180704120000",
	-"forecast": [-{
		"forecast_time": "20180704120000"
	}, -{
		"forecast_time": "20180704150000"
	}, -{
		"forecast_time": "20180704180000"
	}, -{
		"forecast_time": "20180704210000"
	}, -{
		"forecast_time": "20180714120000"
	}]
}]

    至此,问题已全部解决。







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值