下面我将为您介绍如何使用Spring来操作Elasticsearch,并提供两个示例说明。
1. 引入依赖
首先,我们需要在pom.xml
文件中引入Spring Data Elasticsearch的依赖:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>4.0.3</version>
</dependency>
2. 配置Elasticsearch
接着,我们需要在application.properties
文件中配置Elasticsearch的连接信息:
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=localhost:9300
这里我们使用的是本地的Elasticsearch,所以节点为localhost:9300
,对于其他环境,节点地址需要修改。
3. 定义实体类
在使用Spring Data Elasticsearch时,我们需要定义实体类,用于映射Elasticsearch中的文档。下面是一个示例:
@Document(indexName = "blog", createIndex = false)
@Data
public class Blog {
@Id
private Long id;
private String title;
private String content;
@Field(type = FieldType.Date)
private Date createTime;
}
在这个示例中,我们使用了@Document
注解来指定对应的索引名称,同时关闭了自动创建索引;使用@Id
注解指定ID属性;使用@Field
注解指定字段类型为日期类型。
4. Repository接口定义
接下来,我们需要定义一个Repository接口,继承ElasticsearchRepository
,用于操作Elasticsearch:
public interface BlogRepository extends ElasticsearchRepository<Blog, Long> {
}
这个示例中,我们使用了ElasticsearchRepository
接口,泛型参数指定映射的实体类和ID类型。
5. 基本查询
我们可以使用Repository提供的方法来进行Elasticsearch的基础查询,例如:
- 通过ID查询
blogRepository.findById(1L);
- 全文搜索
blogRepository.findByTitleOrContent("spring", "elasticsearch");
- 范围查询
blogRepository.findByCreateTimeBetween(DateUtils.parseDate("2021-01-01"), DateUtils.parseDate("2021-01-31"));
6. 自定义查询
在实际开发中,我们需要进行更加复杂的查询,一般使用@Query
注解来定义自定义的查询方法。例如:
@Query("{\"match\": {\"title\": {\"query\": \"?0\"}}}")
List<Blog> searchByTitle(String keyword);
在这个示例中,我们使用JSON格式的查询语句来查询标题中包含指定关键词的文档。
示例1:实现文本高亮
下面是一个示例:实现搜索结果中的文本高亮效果。首先,在@Document
注解中指定一个设置高亮显示的字段:
@Document(indexName = "blog", createIndex = false)
@Data
public class Blog {
@Id
private Long id;
@Field(type = FieldType.text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String title;
@Field(type = FieldType.text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String content;
@Field(type = FieldType.Date)
private Date createTime;
@Field(type = FieldType.Keyword)
private String tags;
@Field(type = FieldType.Integer)
private Integer status;
@Field(type = FieldType.Keyword, index = false)
private String author; // 设置一个不分词的字段,用于实现高亮显示
}
在这个示例中,我们使用@Field
注解来指定搜索和索引的分词器类型,并在其中添加author
字段用于实现高亮显示。
接着,我们在自定义查询方法中,使用org.springframework.data.elasticsearch.core.SearchHits
类的map(SearchHitMapper mapper)
方法,将查询结果进行映射。
@Override
public Page<Blog> search(String keyword, Integer pageNo, Integer pageSize) {
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
builder.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"));
builder.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>"));
SearchQuery searchQuery = builder.build();
searchQuery.setPageable(PageRequest.of(pageNo - 1, pageSize));
SearchHits<Blog> searchHits = elasticsearchRestTemplate.search(searchQuery, Blog.class);
return searchHits.map(searchHit -> {
Blog blog = searchHit.getContent();
Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
if (highlightFields.containsKey("title")) {
blog.setTitle(highlightFields.get("title").get(0));
}
if (highlightFields.containsKey("content")) {
blog.setContent(highlightFields.get("content").get(0));
}
return blog;
}).map(content -> {
if (StringUtils.isNotBlank(content.getAuthor())) {
content.setTitle(content.getTitle().replace(content.getAuthor(), "<em>" + content.getAuthor() + "</em>"));
}
return content;
}).map(PageImpl::new).getContent();
}
在这个示例中,我们使用NativeSearchQueryBuilder
类来创建查询条件,使用HighlightBuilder.Field
类来指定需要高亮显示的字段。在查询结果中,我们使用org.springframework.data.elasticsearch.core.SearchHits
类的getHighlightFields()
方法来获取高亮显示的信息,并根据信息更新对应的字段内容。
示例2:实现聚合查询
下面是一个示例:在查询结果中,实现对标签(tags)进行聚合查询,统计出现次数前5个标签。
@Override
public Map<String, Long> getTopTags(Integer topN) {
Aggregation aggregation = AggregationBuilders.terms("top_tags").field("tags").order(BucketOrder.count(false)).size(topN).subAggregation(AggregationBuilders.count("tag_count").field("tags"));
AggregatedPage<Blog> aggregatedPage = elasticsearchTemplate.queryForPage(new NativeSearchQueryBuilder().withPageable(PageRequest.of(0, 1)).addAggregation(aggregation).build(), Blog.class);
Map<String, Long> topTagsMap = new HashMap<>();
Aggregations aggregations = aggregatedPage.getAggregations();
if (Objects.nonNull(aggregations)) {
Terms terms = aggregations.get("top_tags");
if (terms != null) {
for (Terms.Bucket bucket : terms.getBuckets()) {
String key = bucket.getKeyAsString();
Long count = bucket.getDocCount();
topTagsMap.put(key, count);
}
}
}
return topTagsMap;
}
在这个示例中,我们使用AggregationBuilders
类的terms()
方法来创建一个聚合查询,统计标签出现次数,并取前topN个标签。在创建查询条件时,我们使用withPageable()
方法指定分页信息,然后使用addAggregation()
方法将聚合查询添加至查询条件中。
执行查询后,我们通过AggregatedPage
对象的getAggregations()
方法获取聚合结果,并遍历Terms
对象中的各个Bucket,获取标签的名称和出现次数。最终将结果封装成Map
类型返回给用户。
以上就是关于在Spring中操作Elasticsearch查询的使用方法的详细攻略,希望对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring 操作elasticsearch查询使用方法 - Python技术站