mongodb计算地理空间距离实例

wildelf 2015-09-17

需求:有很多条件,其中包括根据附近多少米查找信息,这个需要先定位当前人所在的位置(即经纬度),然后在进行这个经纬度的附近进行查找信息,因为之前根据经纬度算地理空间位置是在mysql中进行的,但是发现在mysql中计算很耗CPU,现特改成mongodb来做,mongodb不支持unionall功能,所以mongodb还是不满足:

//判断是否按距离排序
			if(seq == 1 || seq == 0 || seq == 4){
				//默认排序统一采用综合排序
				if(seq == 0){
					seq = 4;
				}
				if(lon != 0 && lat != 0){
				}else{
					seq=2;
				}
			}
			DBObject sortFileds = new BasicDBObject();
			DBObject geoNearFileds = new BasicDBObject();
			geoNearFileds.put("distanceMultiplier", r);
			geoNearFileds.put("near",  new double[]{lon,lat});
			geoNearFileds.put("spherical",true);
			geoNearFileds.put("distanceField", "distance");
			geoNearFileds.put("includeLocs", "position");
			geoNearFileds.put("query", criteria.getCriteriaObject());
			if (nearby!=0) {//选择了附近
				geoNearFileds.put("maxDistance", nearby);
				if (seq==0||seq==4) {
					sortFileds.put("seqScore", -1);
					sortFileds.put("evalGoodCount", -1);
					sortFileds.put("distance", 1);
					if (nearby == 0) {
						sortFileds.put("seqRating", 1);
					}
					sortFileds.put("carNo", 1);
				}
				sortFileds = sort(seq, sortFileds);
			}else{//未选择附近
				if (seq==0||seq==4) {
					sortFileds.put("seqRating", -1);
					sortFileds.put("carNo", 1);
					sortFileds.put("distance", 1);
				}else {
					sortFileds = sort(seq, sortFileds);
				}
			} 

			DBObject geoNear = new BasicDBObject("$geoNear", geoNearFileds);

			DBObject sort = new BasicDBObject("$sort", sortFileds);

			//DBObject match  = new BasicDBObject("$match", criteria.getCriteriaObject());

			DBObject skip  = new BasicDBObject("$skip",(pageNum-1)*pageSize);

			DBObject limit  = new BasicDBObject("$limit",pageSize);

			List<DBObject> dbObjects =  super.aggregate(CarInfo.class, geoNear/*,match*/,skip,limit,sort);

			List<CarInfo> carInfos = new ArrayList<CarInfo>();

			if (CollectionUtils.isEmpty(dbObjects)) {
				return null;
			}
			for (DBObject dbObject : dbObjects) {
				CarInfo carInfo = new CarInfo();
				carInfo = MongoUtils.dbObject2Bean(dbObject, carInfo);
				carInfo.setId(dbObject.get("_id").toString());
				if (tag==1) {
					carInfo.setCoverPic("1"+carInfo.getCoverPic());
				}else {
					carInfo.setCoverPic("2"+carInfo.getCoverPic());
				}
				carInfo.setEvalCount((Integer.valueOf(dbObject.get("evalGoodCount")+"")+Integer.valueOf(dbObject.get("evalMediumCount")+"")+Integer.valueOf(dbObject.get("evalBadCount")+""))+"");
				carInfos.add(carInfo);
			}

这段代码之前使用aggregate$match来进行根据条件查询,发现查询的结果跟实际结果差距很大,至今不知道为何,现改成geoNear的query匹配条件进行查询,结果正确

相关推荐