Spring Boot integra Elasticsearch na prática

1. Introdução

Tenho que usar o Elasticsearch em meu projeto recente, então aprendi brevemente como usá-lo.Algumas das funções avançadas específicas não podem ser exibidas por enquanto, e os recursos são atualmente um pouco limitados, mas algumas necessidades básicas ainda podem ser conhecido. Então escrevi um artigo para resolver o problema e espero que ele possa apontar as deficiências.

2. Instale e configure o Elasticsearch

implantação normal do docker

3. Integre Spring Boot e Elasticsearch

1. Adicione dependências e arquivos de configuração

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
spring:
  elasticsearch:
    rest:
      uris: 127.0.0.1:9200 #可配置多个,以逗号间隔举例: ip,ip
      connection-timeout: 1
      read-timeout: 30

2. Crie um modelo de dados Elasticsearch

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;

/**
 * @BelongsProject: spring-elas
 * @BelongsPackage: com.example.springelas.elas.entity
 * @Author: gepengjun
 * @CreateTime: 2023-09-07  09:16
 * @Description: TODO
 * @Version: 1.0
 */
@Data
@Document(indexName = "book",createIndex = true)
public class Book {
    
    
    @Id
    @Field(type = FieldType.Text)
    private String id;
    @Field(analyzer="ik_max_word")
    private String title;
    @Field(analyzer="ik_max_word")
    private String author;
    @Field(type = FieldType.Double)
    private Double price;
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    @Field(type = FieldType.Date,format = DateFormat.custom, pattern = "8uuuu-MM-dd'T'HH:mm:ss")
    private Date createTime;
    @Field(type = FieldType.Date,format = DateFormat.time)
    private Date updateTime;
    /**
     * 1. Jackson日期时间序列化问题:
     * Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-06-04 15:07:54": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-06-04 15:07:54' could not be parsed at index 10
     * 解决:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     * 2. 日期在ES存为long类型
     * 解决:需要加format = DateFormat.custom
     * 3. java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=5, YearOfEra=2020, MonthOfYear=6},ISO of type java.time.format.Parsed
     * 解决:pattern = "uuuu-MM-dd HH:mm:ss" 即将yyyy改为uuuu,或8uuuu: pattern = "8uuuu-MM-dd HH:mm:ss"
     * 参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats
     */
}

3. Defina a interface do armazém do Elasticsearch

public interface ESBookRepository extends ElasticsearchRepository<Book, String> {
    
    

    List<Book> findByTitleOrAuthor(String title, String author);

    @Highlight(fields = {
    
    
            @HighlightField(name = "title"),
            @HighlightField(name = "author")
    })
    @Query("{\"match\":{\"title\":\"?0\"}}")
    SearchHits<Book> find(String keyword);
}

4. Implementar operações de dados do Elasticsearch

@Service
public class ESBookImpl {
    
    
    @Autowired
    ESBookRepository esBookRepository;

    public void insertBook(Book book){
    
    

       Book a= esBookRepository.save(book);
        System.out.println(a);
    }

    public Book queryBook(String keyWord){
    
    
       return esBookRepository.findById(keyWord).get();
    }
}

4. Operações básicas de consulta e índice

1. Insira e atualize dados

Insira a descrição da imagem aqui

2. Exclua dados e índices

    /**
     * @description: 根据id删除
     * @author: gepengjun
     * @date: 2023/9/7 10:35
     * @param: [keyWord]
     * @return: void
     **/
    public void deleteBook(String keyWord){
    
    
        esBookRepository.deleteById(keyWord);
//        esBookRepository.delete(book);  //可通过实体删除
    }

Primeiro, obtenha todos os dados de acordo com o método findAll fornecido pelo Spring.
Insira a descrição da imagem aqui
Em seguida, chame o método delete e exclua de acordo com o ID.
Você pode ver que os dados com ID 1 não estão mais lá.
Insira a descrição da imagem aqui

3. Consulta condicional e consulta de paginação

Defina um método de consulta de paginação no warehouse do Elasticsearch

 Page<Book> findByTitle(String title, Pageable pageable);

Chame esse método na classe encapsulada de negócios

    public Object pageBook(String author){
    
    
        Pageable pageable= PageRequest.of(0, 3);
       return esBookRepository.findByTitle(author,pageable);
    }

Por fim, chame-o no controle e você poderá ver a execução.
Insira a descrição da imagem aqui

4. Consultas de classificação e agregação

organizar

Esta é a classificação de todas as consultas. Se precisar classificar com base em consultas condicionais, você pode consultar a página acima para configurá-la você mesmo.

    public Object findDESCBook(){
    
    
        //设置排序规则,针对某个字段排序
        Sort sort = Sort.by(Sort.Direction.DESC, "price");
        return esBookRepository.findAll(sort);
    }

Classificar por campo de preço

Insira a descrição da imagem aqui

Consulta de agregação

Ainda existem algumas pequenas falhas nesta consulta agregada.


    @Autowired
    private ElasticsearchOperations elasticsearchOperations;
    /**
     * @description: 聚合查询
     * @author: gepengjun
     * @date: 2023/9/7 11:37
     * @param: []
     * @return: java.lang.Object
     **/
    public Object findAggregationBOOK(String title){
    
    
        Pageable pageable= PageRequest.of(0, 3);
        TermsAggregationBuilder builder1 = AggregationBuilders.terms("taxonomy").field("title.keyword");

        //构建查询
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .addAggregation(builder1)
                .withPageable(pageable)
                .build();

        SearchHits<Book> search = elasticsearchOperations.search(build, Book.class);
        for (SearchHit<Book> bookSearchHit : search) {
    
    
            System.out.println(bookSearchHit.getContent());
        }
        Aggregations aggregations = search.getAggregations();
        Map<String, Aggregation> asMap = aggregations.getAsMap();
        return asMap;
    }

Insira a descrição da imagem aqui

Cenários de aplicação

Consultas agregadas são um recurso importante do Elasticsearch que pode ser usado para extrair informações resumidas significativas e resultados estatísticos de grandes quantidades de dados. A seguir está um resumo de vários cenários comuns de aplicação de consultas agregadas no Elasticsearch:

  1. Análise de dados e estatísticas: as consultas de agregação podem realizar estatísticas e análises em grandes quantidades de dados, como cálculo de médias, somas, valores máximos, valores mínimos, etc. Ele pode ser usado para gerar relatórios, gráficos ou realizar tarefas complexas de análise de dados.

  2. Estatísticas de grupo: as consultas de agregação nos permitem agrupar dados com base em campos especificados e calcular estatísticas para cada grupo. Por exemplo, no comércio eletrônico, os dados de vendas podem ser agrupados de acordo com categorias de produtos para obter vendas ou volume de vendas para cada categoria.

  3. Agregação aninhada: o Elasticsearch oferece suporte ao aninhamento de várias operações de agregação para atender a necessidades estatísticas e analíticas mais complexas. Ao criar vários níveis de agregações aninhadas, você pode detalhar os relacionamentos entre seus dados e obter insights mais detalhados.

  4. Análise temporal: as consultas de agregação são muito úteis na análise de dados de séries temporais. Ele pode agrupar dados de acordo com intervalos de tempo especificados e, em seguida, realizar operações de análise estatística dentro de cada período de tempo. Por exemplo, os dados do log de acesso podem ser analisados ​​ao longo do tempo por horas, dias, semanas ou meses.

  5. Análise de bucket: a agregação de bucket é um método de agregação que divide os dados em diferentes buckets ou intervalos. As condições do intervalo podem ser definidas por meio de intervalo, correspondência de termos ou scripts, e a análise estatística pode ser realizada em cada intervalo.

  6. Contagem de cardinalidade e desduplicação: as consultas de agregação também oferecem suporte a estatísticas de cardinalidade e contagem de desduplicação. Você pode encontrar o número de valores exclusivos em um campo ou contar valores duplicados nele.

  7. Estatísticas de vários campos: o Elasticsearch permite estatísticas de vários campos em uma operação de agregação. Isso é útil para analisar diversas métricas ou dimensões simultaneamente.

5. Consulta avançada e pesquisa de texto completo

1. Correspondência de vários campos e consulta difusa

    /**
     * @description: 多字段匹配查询
     * @author: gepengjun
     * @date: 2023/9/7 15:40
     * @param: [field1, field2]
     * @return: java.util.List<com.example.springelas.elas.entity.Book>
     **/
    List<Book> findByAuthorOrPrice(String field1, String field2);

    /**
     * @description: 针对一个字段模糊查询
     * @author: gepengjun
     * @date: 2023/9/7 15:40
     * @param: [pattern]
     * @return: java.util.List<com.example.springelas.elas.entity.Book>
     **/
    List<Book> findByAuthorLike(String pattern);

2. Consulta de intervalo e consulta de expressão regular

        /**
         * @description: 查询某一个字段根据正则表达式
         * @author: gepengjun
         * @date: 2023/9/7 15:41
         * @param: [regexPattern]
         * @return: java.util.List<com.example.springelas.elas.entity.Book>
         **/
    List<Book> findByAuthorRegex(String regexPattern);

//具体使用即使直接传入一个正则表达式
List<Book> entityList = esBookRepository.findByAuthorRegex("^abc.*");

3. Pesquisa e destaque de texto completo

Este é o destaque

    @Highlight(fields = {
    
    
            @HighlightField(name = "title"),
            @HighlightField(name = "author")
    })
    @Query("{\"match\":{\"title\":\"?0\"}}")
    SearchHits<Book> find(String keyword);

6. Resumo

O uso do EL é o mesmo de alguns frameworks ORM que usamos, então o pacote fornecido pelo spring para interagir com o EL é colocado em dados.

Acho que você gosta

Origin blog.csdn.net/pengjun_ge/article/details/132729939
Recomendado
Clasificación