mongodb集群环境下的地理位置查询错误:use geoNear command rather than $near query

    技术2022-07-10  133

    mongodb集群环境下的地理位置查询

    参考: https://blog.csdn.net/weixin_34376562/article/details/91584482. 由上可知:集群环境不再支持$near,所以会报error:use geoNear command rather than $near query,在项目中整合的springboot下连接mongodb集群的地理位置查询方法也需要更改,连接的库要添加loc的2d索引。

    db.bj_school.createIndex({ "loc" : "2d" })

    参考代码: 链接: https://blog.csdn.net/zhanglf02/article/details/103204354/. 代码部分我们采用springboot的MongoTemplate来操作mongodb。 首先引入依赖:

    <!--springboot整合mongodb--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> </dependency>

    配置文件AppConfig:

    package com.yc.ibikeSeries.conf; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.mongodb.MongoClient; import com.mongodb.ServerAddress; @Configuration @ComponentScan(basePackages="com.yc") @EnableTransactionManagement//查找spring 托管Bean 上是否有 @Transactional注解,如果有,则启用事务管理器 @Transactional(value="tx") public class AppConfig { @Bean("mongoClient") public MongoClient client() { List<ServerAddress> list=new ArrayList<ServerAddress>(); ServerAddress sa1=new ServerAddress("192.168.101.200",23000); ServerAddress sa2=new ServerAddress("192.168.101.201",23000); ServerAddress sa3=new ServerAddress("192.168.101.202",23000); list.add( sa1 ); list.add( sa2 ); list.add( sa3 ); return new MongoClient( list ); //return new MongoClient("192.168.101.200", 27017); } @Bean // MongoTemplate由spring 托管 @Primary public MongoTemplate template() { return new MongoTemplate(factory()); } /** * 功能描述: 创建数据库名称对应的工厂,数据库名称可以通过配置文件导入 * @param * @return:org.springframework.data.mongodb.MongoDbFactory * @since: v1.0 */ @Bean("mongoDbFactory") public MongoDbFactory factory() { return new SimpleMongoDbFactory(client(), "ibike");//ibike为你要操作的库 } }

    写一个接口

    public interface BikeService { public List<Bike> findNearAll(Bike bike); }

    实现这个接口

    @Service @Transactional public class BikeServiceImpl implements BikeService { @Autowired private MongoTemplate mongotemplate; /** *Bike.class为一个javabean类 */ @Override public List<Bike> findNearAll(Bike bike) { //以前连接mongo单节点的地理位置查询方案 //Query query=new Query(); //System.out.println(bike.toString()); NearQuery query1 = NearQuery .near(new Point(bike.getLongitude(),bike.getLatitude())) .maxDistance(new Distance(1500 / 1000, Metrics.KILOMETERS)) .num(20L); // query.addCriteria(Criteria.where("status").is( bike.getStatus() )) // .addCriteria(Criteria.where("loc") // .near(new Point(bike.getLatitude(),bike.getLongitude()))) // .limit(10); GeoResults<Bike> geoResults=this.mongotemplate.geoNear(query1,Bike.class, "bike"); //如果想获取查询结果集是自己封装的数据。只需要在进行一次遍历 List<GeoResult<Bike>> list = geoResults.getContent(); //System.out.println(geoResults); List<Bike> list1=new ArrayList<Bike>(); //再遍历一遍存到list里面 for (GeoResult<Bike> b1: list) { Bike b=new Bike(); b.setBid(b1.getContent().getId()); b.setId(null); b.setLongitude(b1.getContent().getLoc()[0]); b.setLatitude(b1.getContent().getLoc()[1]); b.setLoc(null); list1.add(b); } // for(Bike b:list) { // b.setBid(b.getId()); // b.setId(null); // b.setLongitude(b.getLoc()[1]); // b.setLatitude(b.getLoc()[0]); // b.setLoc(null); // } //查到的数据我用list返回 return list1; } }

    最后如果出现这个错误: longitude/latitude is out of bounds 解决方法: 在mongodb中存储GeoJSON的格式是先存经度后存纬度,即你mongodb里的数据loc下要为这样:“loc”: [经度,纬度],经度它的范围在±180以内,而纬度在±90以内,所以出现这种问题直接找是不是经纬度顺序存储反了即可。

    参考博文:

    springboot+mongodb实现对指定经纬度,半径范围内的数据进行搜索.mongodb——mongo笔记*.mongodb建立地理位置索引出现错误longitude/latitude is out of bounds.
    Processed: 0.012, SQL: 9