Spring MongoDB简易实现查询附近的人功能
文章目录
1.准备
1.创建一个springboot项目,准备一些用户坐标点数据,本案例使用广东博物馆西门分别为(1用户),广州图书馆西门(2用户),南方日报社(3用户)
2.搭建基础结构并编写代码
JSONResult
@Data
@Accessors(chain = true)
public class JSONResult<T> implements Serializable {
/** 状态值 */
private Integer code;
/** 提示信息 */
private String msg;
/** 数据 */
private T data;
public static <T> JSONResult<T> build(int code, String msg, T data) {
return new JSONResult<T>()
.setCode(code)
.setMsg(msg)
.setData(data);
}
}
UserLocation
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_location")
//指定我们UserLocation这个实例中使用的是2dsphere二维球面的索引
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class UserLocation implements java.io.Serializable{
private static final long serialVersionUID = 4508868382007529970L;
@Id
private String id;
private Long userId; //用户id
private GeoJsonPoint location; //x:经度 y:纬度
private String address; //位置描述
private Long created; //创建时间
private Long updated; //更新时间
private Long lastUpdated; //上次更新时间
}
UserLocationServiceImpl
@Service
public class UserLocationServiceImpl {
@Resource
private MongoTemplate mongoTemplate;
public String updateUserLocation(Long userId, Double longitude, Double latitude, String address) {
UserLocation userLocation = new UserLocation();
userLocation.setAddress(address);
userLocation.setLocation(new GeoJsonPoint(longitude, latitude));
userLocation.setUserId(userId);
Query query = Query.query(Criteria.where("userId").is(userLocation.getUserId()));
UserLocation ul = this.mongoTemplate.findOne(query, UserLocation.class);
if (ul == null) {
//新增----mongodb中没有该用户数据
userLocation.setCreated(System.currentTimeMillis());
userLocation.setUpdated(userLocation.getCreated());
userLocation.setLastUpdated(userLocation.getCreated());
this.mongoTemplate.save(userLocation);
return userLocation.getId();
} else {
//更新
Update update = Update
.update("location", userLocation.getLocation())
.set("updated", System.currentTimeMillis())
.set("lastUpdated", ul.getUpdated());
this.mongoTemplate.updateFirst(query, update, UserLocation.class);
}
return ul.getId();
}
}
UserLocationController
@RestController
@RequestMapping("userLocation")
public class UserLocationController {
@Resource
private UserLocationServiceImpl userLocationService;
@Resource
private MongoTemplate mongoTemplate;
@GetMapping("alive")
public JSONResult<String> alive(){
return JSONResult.build(200, "用户定位上发程序还活着!!!!",null );
}
@PostMapping("uploadUserLocation")
public JSONResult<String> uploadUserLocation(Long userId, Double longitude, Double latitude, String address){
String rowId = userLocationService.updateUserLocation(userId, longitude, latitude, address);
JSONResult jsonResult = JSONResult.build(200, "地址生成成功!!",rowId );
return jsonResult;
}
@PostMapping("queryByUserId")
public JSONResult queryByUserId(Long userId){
Query query = Query.query(Criteria.where("userId").is(userId));
UserLocation one = mongoTemplate.findOne(query, UserLocation.class);
if (one == null){
return JSONResult.build(200, "查无该用户坐标位置!!",null);
}
return JSONResult.build(200, "查询成功,查询出坐标为!!",one );
}
@PostMapping("queryNearbyUserFromUserLocation")
public JSONResult<List<UserLocation>> queryNearbyUserFromUserLocation(Double x, Double y, Integer range) {
//找到中心点
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(x, y);
//半径---Metric为接口,里面传入他的具体实现类
Distance distance = new Distance(range / 1000, Metrics.KILOMETERS);
//画圆
Circle circle = new Circle(geoJsonPoint, distance);
Query query = Query.query(Criteria.where("location").withinSphere(circle));
List<UserLocation> userLocations = mongoTemplate.find(query, UserLocation.class);
if (userLocations.isEmpty()){
return JSONResult.build(200, "该用户坐标附近没有其他人!!",null);
}
List<Long> ids = userLocations.stream().map(UserLocation::getUserId).collect(Collectors.toList());
return JSONResult.build(200, "该用户坐标附近的用户分别为"+ids+"!!",userLocations);
}
@PostMapping("userExitNearby")
public JSONResult<List<UserLocation>> queryUserFromUserLocation(Long userId) {
mongoTemplate.remove(new Query().addCriteria(Criteria.where("userId").is(userId)),UserLocation.class);
return JSONResult.build(200, "用户退出附近的人成功!!",null);
}
}
3.测试接口
1.分别存入3位用户
2.测试使用id查用户
3.使用广东博物馆西门的坐标测试附近有多少用户
3.1查1km内有多少用户
3.2查5km内有多少用户
4.退出1号看看,广东博物馆西门1km内还有多少用户
那么只剩下广州图书馆的2用户啦!!!