프로그래밍/Spring Boot

[스프링] 자동완성 기능

연유뿌린빙수 2024. 10. 1. 16:00

검색을 위해서 자동완성 서비스를 제공할 때 주로 2가지를 사용한다.

1. 트라이(Trie) 자료 구조 사용하기

2. like 문법을 이용하여 select하기

 

 

1. Trie 자료 구조 사용하기

트라이에 대한 자료구조 알아보기

https://velog.io/@klloo/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%8A%B8%EB%9D%BC%EC%9D%B4Trie-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0

@Configuration을 통하여 트라이 자료구조를 사용할 수 있도록 Bean을 입력해준다.

 

  • Configuration에 Trie를 Bean으로 등록하기
@Configuration
public class AppConfig {

    @Bean
    public Trie<String, String> trie() {
        return new PatriciaTrie<>();
    }
}

위와 같이 Bean으로 트라이를 등록한다.

그리고 자동완성 AutoComplete라는 클래스를 생성해준다.

 

  • 자동완성에 대한 기본 메서드 정의한 클래스 생성하기
public class AutoComplete {
    private Trie trie = new PatriciaTrie();

    public AutoComplete(Trie trie) {
        this.trie = trie;
    }

    public void add(String s) {
        this.trie.put(s, "world");
    }

    public Object get(String s) {
        return this.trie.get(s);
    }
}

따로 생성한 클래스를 이용하여, 실제로 비즈니스 로직 코드를 작성해둔 Service 코드에 위의 클래스를 이용한다.

 

  • Serviec에 자동완성 기능 구현하기
public void addAutocompleteKeyword(String keyword){
    this.trie.put(keyword, null);
}

public List<String> autocomplete(String keyword) {
    return (List<String>) this.trie.prefixMap(keyword).keySet()
            .stream()
            .limit(10)
            .collect(Collectors.toList());
}

public void deleteAutocompleteKeyword(String keyword) {
    this.trie.remove(keyword);
}

생성해둔 클래스를 이용하여 위와 같은 코드 작성

  • 작성한 키워드 트라이에 저장하기
  • 리스트 형식으로 자동완성 모으기
  • 트라이에 저장된 데이터 지우기

 

  • Controller에 service에서 생성한 자동완성 호출해 사용하기
var result = this.companyService.autocomplete(keyword);

 

 

 

2. like 문법을 사용하기

  • Reposiotory의 네임드 메서드를 사용하기
Page<CompanyEntity> findByNameStartingWithIgnoreCase(String s, Pageable pageable);
  • Servicie에 reposiotory의 메서드 사용
    public List<String> getCompanyNamesByKeyword(String keyword) {
        
        Pageable limit = PageRequest.of(0, 10);
        Page<CompanyEntity> companyEntities = this.companyRepository.findByNameStartingWithIgnoreCase(keyword, limit);
        return companyEntities.stream()
                    .map(e -> e.getName())
                    .collect(Collectors.toList());
    }