Diretório de artigos
- 1. Introdução
- 2. Instale e configure o Elasticsearch
- 3. Integre Spring Boot e Elasticsearch
- 4. Operações básicas de consulta e índice
- 5. Consulta avançada e pesquisa de texto completo
- 6. Resumo
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
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
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.
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á.
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.
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
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;
}
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:
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.