implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' implementation group: 'org.elasticsearch.client', name: 'elasticsearch-rest-high-level-client', version: '7.17.23'@Configuration
public class Config extends ElasticsearchConfiguration{
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
}
}
ElasticsearchOperations elasticsearchOperations//결과 값은 SearchHits<T> 객체를 활용하여 총 결과 개수를 받아올 수 있음
//옵션으로는 List<T>, Stream<T>, List<SearchHit<T>>, Stream<SearchHit<T>>, SearchPage<T> 등 사용 가능
public interface TestRepository extends ElasticsearchRepository<Test, String> {
SearchHits<Test> findByTitle(String title);
SearchHits<Test> findByContent(String content);
}
참고) https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-bool-prefix-query.html
https://esbook.kimjmin.net/05-search/5.1-query-dsl
https://velog.io/@haden/spring-Spring-%EC%97%90%EC%84%9C-Elastic-Search-%ED%99%9C%EC%9A%A9-1
https://docs.spring.io/spring-data/elasticsearch/reference/elasticsearch/template.html
Person person = elasticsearchOperations.get(id.toString(), Person.class);으로 가져오기// 간단한 쿼리
Criteria criteria = new Criteria("price").is(42.0);
Query query = new CriteriaQuery(criteria);
// 조금 복잡해진 쿼리
Criteria miller = new Criteria("lastName").is("Miller")
.subCriteria(
new Criteria().or("firstName").is("John")
.or("firstName").is("Jack")
);
Query query = new CriteriaQuery(criteria);
// 스트링 쿼리
Query query = new StringQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } ");
SearchHits<Person> searchHits = operations.search(query, Person.class);
// 네이티브 쿼리
Query query = NativeQuery.builder()
.withAggregation("lastNames", Aggregation.of(a -> a
.terms(ta -> ta.field("lastName").size(10))))
.withQuery(q -> q
.match(m -> m
.field("firstName")
.query(firstName)
)
)
.withPageable(pageable)
.build();
SearchHits<Person> searchHits = operations.search(query, Person.class);
@Document(indexName = "alcohols") // 인덱스 이름 설정, 인덱스를 자동생성하는 옵션인 createIndex는 디폴트값이 true이므로 명시하지 않아도 된다
@Getter
@Setter
@Setting(replicas = 0) // 레플리카 개수조절, 운영시에는 노드 개수를 늘리고 레플리카 개수를 늘려 안정적으로 해야한다
public class AlcoholDocument {
// Id 어노테이션을 특정 속성을 달아주거나, 속성명이 Id인 필드값을 생셩하면 es의 _id와 자동연결
// _id와 연결되면 타입과 인덱싱이 강제
// 따라서 DB의 id값을 담는 필드인 alcoholId는 따로 빼줌
@Id
private String id;
// 각 필드의 타입을 매핑하고, 분석기(analyzer) 설정가능
// 복합적인 설정이 필요한 경우 FieldType.Object를 달아주고 inner class를 새로 생성해서 클래스 내부에서 타입매핑
// 인덱싱을 원하지 않는 필드는 index=false 적용
@Field(type = FieldType.Long, index = false, docValues = false)
private Long alcoholId;
// 똑같은 String이지만 단어가 존재하는 return 해준다
@Field(type = FieldType.Text, analyzer = "nori")
private String title;
// 키워드는 완전히 똑같이 검색해야 검색이 된다
@Field(type = FieldType.Keyword, index = false, docValues = false)
private String category;
@Field(type = FieldType.Object)
private List<TagDocument> tags = new ArrayList<>();
// @WriteOnlyProperty
// searchKeys 리스트는 추후 검색 조건으로 사용되지만, 검색결과에는 띄우지 않는 속성
// 어노테이션을 달아 인덱싱할 때는 넣어주고, 추후 검색 결과를 불러올 때는 값을 가져오지 않음
@Field(type = FieldType.Object)
@WriteOnlyProperty
private List<AlcSearchKeyDocument> searchKeys = new ArrayList<>();
// LocalDateTime 타입 지정, 이름도 지정할 수 있다
@Field(name = "producer_created_at", type = FieldType.Date, format = DateFormat.basic_date_time)
private LocalDateTime producerCreatedAt;
참고)
https://j-1001000.tistory.com/1
https://velog.io/@yeomyaloo/%EC%87%BC%ED%95%91%EB%AA%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1-%EC%84%9C%EC%B9%98elasticsearch%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%97%B0%EB%8F%99%ED%95%B4%EB%B3%B4%EC%9E%90
https://ksb-dev.tistory.com/324