[Spring/Redis] Redis 문서 정리(Search With Redis)

2024. 6. 11. 17:22·Redis/Redis 개념
728x90
반응형
SMALL

이번 문서 정리는 아래 링크 내용입니다!
이번에도 내용 가장 아래에 간단히 내용을 요약해 올려두겠습니다:)

https://redis.io/learn/develop/java/redis-and-spring-course/lesson_7

Redis를 사용한 검색

저자: Brian Sam-Bodden, Redis 개발자 옹호자

목적

Redis의 내장된 검색 및 쿼리 엔진을 활용하여 SQL과 NoSQL 시스템 간의 쿼리 간극을 메우는 방법을 학습합니다. 주로 두 가지 일상적인 사용 사례에 중점을 둡니다: 풀 텍스트 검색과 자동 완성.

학습 내용

  • Redis를 사용하여 검색 인덱스를 생성하는 방법
  • Spring Boot 애플리케이션에서 Redis를 사용하여 검색 기능을 구현하는 방법
  • Redis 제안 기능을 사용하여 자동 완성을 구현하는 방법

문제 발생 시:

  • 이 레슨의 진행 상황은 redi2read GitHub 저장소에서 확인할 수 있습니다.

Redis Stack 검색 및 쿼리 엔진

Redis Stack은 Redis의 소스 사용 가능 버전으로, Redis에서 쿼리, 보조 인덱싱, 풀 텍스트 검색을 수행할 수 있습니다. Redis Stack은 정렬된 세트와 같은 내부 데이터 구조를 사용하지 않고 Redis에 보조 인덱스를 구현합니다. 이를 통해 다중 필드 쿼리, 집계 및 풀 텍스트 검색과 같은 고급 기능을 제공합니다. 이러한 기능을 통해 Redis를 주 데이터베이스로 사용하여 복잡한 쿼리를 수행하고, 데이터를 업데이트 및 인덱싱하는 코드를 추가하지 않고도 데이터를 액세스할 수 있습니다.

spring-redisearch 사용하기

Spring Redis Search는 LettuSearch를 기반으로 한 라이브러리로, Spring 애플리케이션에서 Redis Stack에 접근할 수 있게 합니다. LettuSearch는 인기 있는 Redis Java 클라이언트 라이브러리 Lettuce를 기반으로 한 Redis Stack의 Java 클라이언트입니다.

spring-redisearch 의존성 추가

Maven pom.xml에 다음 의존성을 추가합니다:

<dependency>
  <groupId>com.redislabs</groupId>
  <artifactId>spring-redisearch</artifactId>
  <version>3.0.1</version>
</dependency>

검색 인덱스 생성

인덱스를 생성하려면 인덱싱할 필드와 그 타입을 나열하는 스키마를 정의해야 합니다. Book 모델의 경우, 네 가지 필드를 인덱싱합니다:

  • 제목 (Title)
  • 부제목 (Subtitle)
  • 설명 (Description)
  • 저자 (Authors)

인덱스 생성은 FT.CREATE 명령을 사용하여 수행됩니다. 검색 인덱스를 생성하는 코드는 다음과 같습니다:

CreateBooksSearchIndex.java 생성

package com.redislabs.edu.redi2read.boot;

import com.redislabs.edu.redi2read.models.Book;
import com.redislabs.lettusearch.CreateOptions;
import com.redislabs.lettusearch.Field;
import com.redislabs.lettusearch.RediSearchCommands;
import com.redislabs.lettusearch.StatefulRediSearchConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import io.lettuce.core.RedisCommandExecutionException;
import lombok.extern.slf4j.Slf4j;

@Component
@Order(6)
@Slf4j
public class CreateBooksSearchIndex implements CommandLineRunner {

  @Autowired
  private StatefulRediSearchConnection<String, String> searchConnection;

  @Value("${app.booksSearchIndexName}")
  private String searchIndexName;

  @Override
  @SuppressWarnings({ "unchecked" })
  public void run(String... args) throws Exception {
    RediSearchCommands<String, String> commands = searchConnection.sync();
    try {
      commands.ftInfo(searchIndexName);
    } catch (RedisCommandExecutionException rcee) {
      if (rcee.getMessage().equals("Unknown Index name")) {

        CreateOptions<String, String> options = CreateOptions.<String, String>builder()//
            .prefix(String.format("%s:", Book.class.getName())).build();

        Field<String> title = Field.text("title").sortable(true).build();
        Field<String> subtitle = Field.text("subtitle").build();
        Field<String> description = Field.text("description").build();
        Field<String> author0 = Field.text("authors.[0]").build();
        Field<String> author1 = Field.text("authors.[1]").build();
        Field<String> author2 = Field.text("authors.[2]").build();
        Field<String> author3 = Field.text("authors.[3]").build();
        Field<String> author4 = Field.text("authors.[4]").build();
        Field<String> author5 = Field.text("authors.[5]").build();
        Field<String> author6 = Field.text("authors.[6]").build();

        commands.create(
          searchIndexName, //
          options, //
          title, subtitle, description, //
          author0, author1, author2, author3, author4, author5, author6 //
        );

        log.info(">>>> Created Books Search Index...");
      }
    }
  }
}

설명

  • StatefulRediSearchConnection을 주입하여 동기화 모드에서 검색 명령에 접근합니다.
  • sync() 메서드를 사용하여 검색 명령의 인스턴스를 얻습니다.
  • FT.INFO 명령을 사용하여 인덱스가 존재하는지 확인합니다.
  • 인덱스가 없으면 CreateOptions 객체를 생성하고 필드 객체를 만듭니다.
  • create 메서드를 호출하여 인덱스를 생성합니다.

풀 텍스트 검색 쿼리

Redis Stack은 풀 텍스트 검색 엔진을 제공하여 강력한 쿼리를 실행할 수 있습니다. 예를 들어, "networking"과 관련된 모든 책을 검색하려면 다음 명령을 실행합니다:

127.0.0.1:6379> FT.SEARCH books-idx "networking" RETURN 1 title

이를 통해 "networking" 관련 책들의 제목을 반환합니다.

BooksController에 검색 기능 추가

검색 기능을 BooksController에 추가하려면 다음 코드를 사용합니다:

@Value("${app.booksSearchIndexName}")
private String searchIndexName;

@Autowired
private StatefulRediSearchConnection<String, String> searchConnection;

@GetMapping("/search")
public SearchResults<String,String> search(@RequestParam(name="q")String query) {
  RediSearchCommands<String, String> commands = searchConnection.sync();
  SearchResults<String, String> results = commands.search(searchIndexName, query);
  return results;
}

자동 완성 제안 추가 및 가져오기

Redis Stack은 자동 완성 기능을 제공하여 검색 정밀도를 향상시킵니다. 자동 완성 기능을 구현하려면 다음과 같은 명령을 사용합니다:

  • FT.SUGADD: 자동 완성 사전에 제안 문자열 추가
  • FT.SUGGET: 문자열에 대한 제안 목록 가져오기
  • FT.SUGDEL: 자동 완성 사전에서 제안 문자열 삭제
  • FT.SUGLEN: 자동 완성 사전의 크기 반환

CreateAuthorNameSuggestions.java 생성

package com.redislabs.edu.redi2read.boot;

import com.redislabs.edu.redi2read.repositories.BookRepository;
import com.redislabs.lettusearch.RediSearchCommands;
import com.redislabs.lettusearch.StatefulRediSearchConnection;
import com.redislabs.lettusearch.Suggestion;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Order(7)
@Slf4j
public class CreateAuthorNameSuggestions  implements CommandLineRunner {

  @Autowired
  private RedisTemplate<String, String> redisTemplate;

  @Autowired
  private BookRepository bookRepository;

  @Autowired
  private StatefulRediSearchConnection<String, String> searchConnection;

  @Value("${app.autoCompleteKey}")
  private String autoCompleteKey;

  @Override
  public void run(String... args) throws Exception {
    if (!redisTemplate.hasKey(autoCompleteKey)) {
      RediSearchCommands<String, String> commands = searchConnection.sync();
      bookRepository.findAll().forEach(book -> {
        if (book.getAuthors() != null) {
          book.getAuthors().forEach(author -> {
            Suggestion<String> suggestion = Suggestion.builder(author).score(1d).build();
            commands.sugadd(autoCompleteKey, suggestion);
          });
        }
      });

      log.info(">>>> Created Author Name Suggestions...");
    }
  }
}

설명

  • 자동 완성 사전의 키 존재 여부를 확인하여 한 번만 실행되도록 합니다.
  • BookRepository를 사용하여 모든 책을 반복하고 각 저자를 사전에 추가합니다.

컨트롤러에 자동 완성 기능 추가

자동 완성 기능을 BooksController에 추가하려면 다음 코드를 사용합니다:

@Value("${app.autoCompleteKey}")
private String autoCompleteKey;

@GetMapping("/authors")
public List<Suggestion<String>> authorAutoComplete(@RequestParam(name="q")String query) {
  RediSearchCommands<String

, String> commands = searchConnection.sync();
  SuggetOptions options = SuggetOptions.builder().max(20L).build();
  return commands.sugget(autoCompleteKey, query, options);
}

위의 코드로 자동 완성 기능을 사용하여 저자 이름을 검색할 수 있습니다. 예를 들어, "brian s"를 입력하면 해당하는 저자 이름 제안 목록을 반환합니다.

Redis를 사용한 검색 요약

목적

Redis의 검색 및 쿼리 엔진을 활용하여 SQL과 NoSQL 시스템 간의 쿼리 간극을 메우는 방법을 학습하고, 풀 텍스트 검색과 자동 완성을 구현하는 방법을 다룹니다.

학습 내용

  1. Redis에서 검색 인덱스 생성:

    • spring-redisearch와 lettusearch 라이브러리를 사용하여 검색 인덱스를 생성합니다.
    • FT.CREATE 명령을 사용하여 Book 모델의 제목, 부제목, 설명 및 저자 필드를 인덱싱합니다.
  2. Spring Boot 애플리케이션에서 검색 기능 구현:

    • CreateBooksSearchIndex 클래스를 작성하여 검색 인덱스를 생성합니다.
    • Redis CLI를 사용하여 인덱스가 생성되었는지 확인합니다.
  3. 풀 텍스트 검색 쿼리:

    • FT.SEARCH 명령을 사용하여 특정 키워드가 포함된 문서를 검색합니다.
    • 예를 들어, "networking" 키워드를 포함하는 모든 책을 검색합니다.
    • BooksController에 검색 기능을 추가하여 사용자가 쿼리 파라미터를 통해 검색할 수 있게 합니다.
  4. 자동 완성 제안 추가 및 가져오기:

    • Redis Stack의 자동 완성 기능을 사용하여 사용자가 입력하는 동안 검색 결과를 안내합니다.
    • FT.SUGADD, FT.SUGGET, FT.SUGDEL, FT.SUGLEN 명령을 사용하여 자동 완성 사전을 관리합니다.
    • CreateAuthorNameSuggestions 클래스를 작성하여 책의 저자 이름을 자동 완성 사전에 추가합니다.
    • BooksController에 자동 완성 기능을 추가하여 사용자가 저자 이름을 입력하면 자동 완성 제안을 제공합니다.

결론

Redis Stack의 검색 및 쿼리 엔진을 활용하여 Spring Boot 애플리케이션에서 강력한 풀 텍스트 검색과 자동 완성 기능을 구현할 수 있습니다. 이를 통해 사용자 경험을 향상시키고, 복잡한 쿼리 요구사항을 효과적으로 처리할 수 있습니다.

728x90
반응형
SMALL

'Redis > Redis 개념' 카테고리의 다른 글

Trie와 Redis ZSET 비교: 키워드 자동완성 기능에 가장 효율적인 방법은?  (2) 2024.12.17
Redis기본 개념, 자료구조  (2) 2024.06.12
[Spring/Redis] Redis 문서 정리(User Roles, Secondary Indexes)  (0) 2024.06.11
[Spring/Redis] Redis문서 정리(Object Mapping & Redis Repository)  (0) 2024.06.11
[Spring/Redis] Redis문서정리(Redis Spring 시작하기)  (0) 2024.06.11
'Redis/Redis 개념' 카테고리의 다른 글
  • Trie와 Redis ZSET 비교: 키워드 자동완성 기능에 가장 효율적인 방법은?
  • Redis기본 개념, 자료구조
  • [Spring/Redis] Redis 문서 정리(User Roles, Secondary Indexes)
  • [Spring/Redis] Redis문서 정리(Object Mapping & Redis Repository)
공부하고 기억하는 공간
공부하고 기억하는 공간
IT 비전공자로 시작하여 훌륭한 개발자가 되기 위해 공부하고 있는 공간입니다. 틀린 내용이나 부족한 부분이 있으면 댓글로 알려주세요 바로 수정하겠습니다.
    250x250
  • 공부하고 기억하는 공간
    IT - railroad
    공부하고 기억하는 공간
  • 전체
    오늘
    어제
    • 분류 전체보기 (325)
      • 면접 준비 (22)
        • OS (6)
        • Spring Security (0)
        • Java (3)
        • DB (11)
        • Network (3)
      • ElasticSearch (2)
      • Kafka (4)
      • Spring (22)
        • Spring Cloud (7)
        • Security6 (5)
        • JPA (12)
        • 프로젝트 리팩토링 회고록 (4)
        • Logging (8)
        • Batch (2)
      • Redis (17)
        • Redis 개념 (8)
        • Redis 채팅 (5)
        • Redis 읽기쓰기 전략 (1)
      • AWS (11)
      • 리눅스 (29)
        • 리눅스 마스터 2급 (5)
        • 네트워크(기초) (7)
        • 리눅스의 이해 (6)
        • 리눅스의 설치 (2)
        • 리눅스 운영 및 관리 (6)
      • JAVA-기초 (16)
        • JAVA기본 (11)
        • Design Pattern (5)
      • JSP (27)
        • JSP 기본 개념 (10)
        • JSP (1)
      • SQL (1)
      • TIL (36)
      • 문제 풀이 (2)
        • Programmers (9)
        • 백준 문제풀이 (28)
      • JavaScript (10)
      • HTML (17)
      • Ngrinder (1)
        • Ngrinder 문서 정리 (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      jsp request
      Springframework
      java
      springsecurity
      자바
      레디스
      JSP
      JavaScript
      자바 반복문
      자바 면접질문
      HTML
      JS
      프로그래머스
      Spring Data Redis
      자바 알고리즘
      리눅스마스터2급
      리눅스마스터2급정리
      CSS
      스프링프레임워크
      자바기초
      백준
      Spring
      redis 채팅
      jsp기초
      자바 면접
      spring redis
      redis
      Til
      리눅스
      자바스크립트
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    공부하고 기억하는 공간
    [Spring/Redis] Redis 문서 정리(Search With Redis)
    상단으로

    티스토리툴바