import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "User_Location")
//联合索引,可以加速搜索
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class UserLocation implements java.io.Serializable {
private static final long serialVersionUID = 4508868382007529970L;
@Id
private ObjectId id;
@Indexed
private Long userId; //用户id
private GeoJsonPoint location; //x:经度 y:纬度
private String address; //位置描述
private Long create_time; //创建时间
private Long update_time; //更新时间
private Long lastUpdated; //上次更新时间
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserLocationVo implements Serializable {
private static final long serialVersionUID = 4133419501260037769L;
private String id;
private Long userId; //用户id
private Double longitude; //经度
private Double latitude; //维度
private String address; //位置描述
private Long create_time; //创建时间
private Long update_time; //更新时间
private Long lastUpdated; //上次更新时间
// MongoDB的GeoJsonPoint 不能直接被序列化!所以需要我们使用vo收发数据
public static final UserLocationVo format(UserLocation userLocation) {
UserLocationVo userLocationVo = new UserLocationVo();
userLocationVo.setAddress(userLocation.getAddress());
userLocationVo.setCreate_time(userLocation.getCreate_time());
userLocationVo.setId(userLocation.getId().toHexString());
userLocationVo.setLastUpdated(userLocation.getLastUpdated());
userLocationVo.setUpdate_time(userLocation.getUpdate_time());
userLocationVo.setUserId(userLocation.getUserId());
userLocationVo.setLongitude(userLocation.getLocation().getX());
userLocationVo.setLatitude(userLocation.getLocation().getY());
return userLocationVo;
}
public static final List<UserLocationVo> formatToList(List<UserLocation> userLocations) {
List<UserLocationVo> list = new ArrayList<>();
for (UserLocation userLocation : userLocations) {
list.add(format(userLocation));
}
return list;
}
}
try {
// 查询有没有这个人的地理位置记录
Query query = new Query();
query.limit(1);
query.addCriteria(Criteria.where("userId").is("你自己传入的账号"));
UserLocation user_location = mongoTemplate.findOne(query, UserLocation.class, "User_Location");
Update update = new Update();
// 设置经纬度
中⼼点 下面经纬度由前端传参
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(longitude, latitude);
update.set("location", geoJsonPoint);
// 判断有没有这个用户的地理位置记录,如果没有地理位置记录,就追加创建、更新、上次更新时间,否则更新、上次更新时间
long currentTimeMillis = System.currentTimeMillis();
if (user_location != null) {
update.set("update_time", currentTimeMillis);
update.set("lastUpdated", user_location.getUpdate_time());
} else {
update.set("create_time", currentTimeMillis);
update.set("update_time", currentTimeMillis);
update.set("lastUpdated", currentTimeMillis);
}
long modifiedCount = mongoTemplate.upsert(query, update, "User_Location").getModifiedCount();
log.info("受到影响的结果有:{}条", modifiedCount);
} catch (Exception e) {
log.error("数据库操作异常" + e);
return Results.error("数据库操作异常");
}
List<UserLocationVo> userLocationVos = null;
try {
// 设置地理位置中⼼点
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(longitude, latitude);
// 转换为2dsphere的 距离 range单位是千米
Distance distance = new Distance(range / 1000, Metrics.KILOMETERS);
//画⼀个圆
Circle circle = new Circle(geoJsonPoint, distance);
Query query = new Query();
query.addCriteria(Criteria.where("location").withinSphere(circle));
userLocationVos = UserLocationVo.formatToList(this.mongoTemplate.find(query, UserLocation.class, "User_Location"));
} catch (Exception e) {
log.error("数据库操作异常" + e);
return Results.error("数据库操作异常");
}
特殊说明: 解决问题的光鲜,藏着磕Bug的痛苦。 万物皆入轮回,谁也躲不掉! 以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!