unable to find index for $geoNear query


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
    		]
    	}
    }
    座標は経度、緯度です.
  • 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
  • エラー解決

  • mongodyでは、2dsphereインデックスを特定のフィールドで生成する必要があります.
    db.places.createIndex( { location: "2dsphere" } )

  • コメントサイト


    Spring Data MongoDB - Aggregation Operation - 02
    $geoNear (aggregation)
    例コンテキストベースのMongoDBロケーションクエリー
    [MongoDB]MongoDBとGeoJSONを使用して近接位置を決定