unable to find index for $geoNear query

Volc·2022년 4월 5일
0

Error

목록 보기
31/64

Error

  • mongoDB 데이터
    {
    	"_id" : ObjectId("6245f6edf2aa51bc5bae594c"),
    	"name" : "제주커피박물관 Baum",
    	"location" : {
    		"type" : "Point",
    		"coordinates" : [
    			126.8990639,
    			33.4397954
    		]
    	}
    }
    {
    	"_id" : ObjectId("6245f6eef2aa51bc5bae594d"),
    	"name" : "신산리 마을카페",
    	"location" : {
    		"type" : "Point",
    		"coordinates" : [
    			126.8759347,
    			33.3765812
    		]
    	}
    }

    coordinates는 경도, 위도 순이다.

  • VO
    • VisitJejuLocation
      package kr.pe.playdata.domain;
      
      import lombok.Data;
      import org.springframework.data.annotation.Id;
      import org.springframework.data.mongodb.core.mapping.Document;
      
      @Data
      @Document(collection="places")
      public class VisitJejuLocation {
      
          @Id
          private String id;
          private String name;
          private Location location;
      }
    • Location
      package kr.pe.playdata.domain;
      
      import lombok.Data;
      import org.springframework.data.geo.Point;
      import org.springframework.data.mongodb.core.mapping.Document;
      
      import java.util.List;
      
      @Data
      @Document
      public class Location {
      
          private String type;
          private List<String> coordinates;
      }
  • 컨트롤러
    package kr.pe.playdata.controller;
    
    import kr.pe.playdata.domain.VisitJejuLocation;
    import kr.pe.playdata.service.LocationService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.geo.Distance;
    import org.springframework.data.geo.Metrics;
    import org.springframework.data.geo.Point;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/map")
    public class MapController {
        @Autowired
        private LocationService locationService;
    
        @GetMapping("/findNear")
        public List<VisitJejuLocation> findNear(
                @RequestParam String longtitude,
                @RequestParam String latitude,
                @RequestParam double distance
        ){
            Point p = new Point(Double.valueOf(longtitude), Double.valueOf(latitude));
            Distance d = new Distance(distance, Metrics.KILOMETERS);
            List<VisitJejuLocation> li = locationService.findNear(p,d);
            return li;
        }
    }
  • Service
    • Interface
      package kr.pe.playdata.service;
      
      import kr.pe.playdata.domain.VisitJejuLocation;
      import org.springframework.data.geo.Distance;
      import org.springframework.data.geo.Point;
      
      import java.util.List;
      
      public interface LocationService {
          public List<VisitJejuLocation> findNear(Point p, Distance d);
      }
    • Implements
      package kr.pe.playdata.service.impl;
      
      import kr.pe.playdata.domain.VisitJejuLocation;
      import kr.pe.playdata.repository.LocationMongoRepo;
      import kr.pe.playdata.service.LocationService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.data.geo.Distance;
      import org.springframework.data.geo.Point;
      import org.springframework.stereotype.Service;
      
      import java.util.List;
      
      @Service
      public class LocationServiceImpl implements LocationService {
      
          @Autowired
          private LocationMongoRepo locationMongoRepo;
      
          public List<VisitJejuLocation> findNear(Point p, Distance d){
              return locationMongoRepo.findByLocationNear(p, d);
          }
      }
  • Repository
    package kr.pe.playdata.repository;
    
    import kr.pe.playdata.domain.VisitJejuLocation;
    import org.springframework.data.geo.Distance;
    import org.springframework.data.geo.Point;
    import org.springframework.data.mongodb.repository.MongoRepository;
    import org.springframework.data.mongodb.repository.Query;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface LocationMongoRepo extends MongoRepository<VisitJejuLocation, String> {
        List<VisitJejuLocation> findByLocationNear(Point p, Distance d);
    }
  • 위와 같이 코드를 작성 후 postman으로 다음과 같이 보냈다.
    localhost:8080/map/findNear?latitude=33.43&longtitude=126.89&distance=7
  • 결과는 다음과 같이 에러가 발생하였다.
    planner returned error :: caused by :: unable to find index for $geoNear query' on server xx.xxx.xxx.xxx:27017; nested exception is com.mongodb.MongoQueryException: Query failed with error code 291 and error message 'error processing query: ns=jeju.placesTree: GEONEAR  field=location maxdist=0.0010975 isNearSphere=1

Error 해결

  • mongoDB에 특정 field에 2dsphere index를 생성해줘야 한다.
    db.places.createIndex( { location: "2dsphere" } )

참고 사이트

Spring Data MongoDB - Aggregation Operation - 02

$geoNear (aggregation)

예제로 배워보는 상황 별 MongoDB 위치 기반 쿼리

[MongoDB] MongoDB와 GeoJSON을 이용하여 근접 위치 확인하기

profile
미래를 생각하는 개발자

0개의 댓글