前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MongoDB 整合GEO

MongoDB 整合GEO

作者头像
收心
发布2022-01-19 11:21:47
6710
发布2022-01-19 11:21:47
举报
文章被收录于专栏:Java实战博客

实体类

代码语言:javascript
复制
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; //上次更新时间
}

实体类VO

代码语言:javascript
复制
@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;
    }
}

伪添加用户地理位置代码

代码语言:javascript
复制
        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("数据库操作异常");
        }

查询附近用户

代码语言:javascript
复制
        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的痛苦。 万物皆入轮回,谁也躲不掉! 以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实体类
  • 实体类VO
  • 伪添加用户地理位置代码
  • 查询附近用户
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档