Spring Data Elasticsearch에서 geo_point를 매핑하는 방법

JDooo·2024년 9월 15일
0
post-thumbnail

개요

SSAFY 특화 프로젝트를 수행하면서 지리 정보를 다뤄야 할 일이 생겼다. Elasticsearch(ES)에 지리 정보를 다룰 수 있는 기능들이 많아서 이를 활용하기로 했다. Spring에서 기능을 사용하는 방법을 알아보고 활용해보자.

Spring Data Elasticsearch

Spring Data Elasticsearch provides repository support for the Elasticsearch database. It eases development of applications with a consistent programming model that need to access Elasticsearch data sources.

위 글은 공식문서의 소개를 그대로 가져온 것이다.번역하면 Spring Data Elasticsearch는 ES에 대한 repository를 지원하며, Spring에서 제공하는 다른 Data 라이브러리(JPA, Redis 등)와 공통된 방식으로 사용할 수 있다고 한다.

기본적인 설정법과 사용법은 공식문서에 잘 나와 있으니, 이번 글에서는 Spring Data Elasticsearch에서 ES의 geo_point를 어떻게 사용할 수 있는지 알아보겠다.

Document 정의 방법

Spring Data Elasticsearch에서는 JPA Entity처럼 애노테이션을 사용해서 ES의 Document를 정의한다.

@Getter  
@Document(indexName = "books")  
public class Book {  
  
    @Id
    private String id;  
  
    @Field(type = FieldType.Text)  
    private String name;  
  
    @Field(type = FieldType.Text)  
    private String summary;  
  
    @Field(type = FieldType.Integer)  
    private Integer price;  
  
    public Book(String name, String summary, Integer price) {  
       this.name = name;  
       this.summary = summary;  
       this.price = price;  
    }  
}

이렇게 Document 클래스를 생성한다고 Index가 생성되는건 아니다. Repository도 함께 만들어 주어야 한다.

public interface BookRepository extends Repository<Book, String> {  
}

Springboot 실행 시 org.springframework.data.repository.Repository 인터페이스를 상속 받은 인터페이스를 자동으로 탐지해서 Repository의 데이터 타입이 @Document일 경우 index 존재 유무를 확인하고 없으면 생성한다.

geo_point 매핑 방법

ES에서 geo_point 기능을 사용하기 위해서는 해당 필드의 매핑 타입이 "geo_point"로 선언되어야 한다. "geo_point" 값들은 다양한 방식으로 입력 가능한데 문서에 따르면 object, text, geohash, 실수 배열 등 정말 다양한 형식으로 입력이 가능하다.

Spring에도 geo_point를 위한 클래스가 있다. 바로 org.springframework.data.geo.Point이다. 멤버로 lat(위도), lon(경도)를 가지고 있는 데이터 타입이다. 이를 Docuement의 필드로 지정하면 바로 적용될까?

@Document(indexName = "markers")  
public class Marker {  
  
    @Id
    private String id;  
  
    private Point point;  
}

안타깝게도 아래와 같이 매핑이 생성되지 않는다.

GET http://localhost:9200/markers/_mapping?pretty
{
  "markers" : {
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        }
      }
    }
  }
}

Spring의 Point를 geo_point로 매핑하기 위해서는 ES의 @GeoPointField 애노테이션을 사용해야 한다.

@Document(indexName = "markers")  
public class Marker {  

	// ...

	@GeoPointField
	private Point point;  
}
GET http://localhost:9200/markers/_mapping?pretty
{
  "markers" : {
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "point" : {
          "type" : "geo_point"
        }
      }
    }
  }
}

위처럼 이제 잘 매핑되는 것을 볼 수 있다.

애노테이션을 사용하고 싶지 않다면 ES에서 지원하는 org.springframework.data.elasticsearch.core.geo.GeoPoint를 사용하면 된다.

@Document(indexName = "markers")  
public class Marker {  

	// ...
	
	private GeoPoint point;  
}

참고

0개의 댓글