Elasticsearch7.x集成网上一大堆,随便百度就行
此文章仅针对写分页查询时传入各种参数,然后的不同写法,仅供参考
实体中的部分代码
@Document(indexName = "appeal_doc")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class AppealDoc implements Serializable {
@Id
@Field(type = FieldType.Text)
private String id;
@Field(type = FieldType.Keyword)
private String city;
......
......
......
@Field(type = FieldType.Date)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date appealDate;
@Field(type = FieldType.Text)
private String appealContent;
}
分页查询的部分代码
service上注释也写了,仅针对实体上Field类型为Text,Keyword,Date三种作为示例
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// keyword不分词,相当于: t.city = 'cities'
if(StrUtil.isNotEmpty(query.getCities())) {
String cities = query.getCities();
boolQueryBuilder.must(QueryBuilders.termQuery("city", cities));
}
// keyword不分词,相当于 and t.complaintEnterprise in ( 'enterprises[0]', 'enterprises[1]', ...)
if(StrUtil.isNotEmpty(query.getEnterprises())) {
String[] enterprises = query.getEnterprises().split(",");
boolQueryBuilder.must(QueryBuilders.termsQuery("complaintEnterprise", enterprises));
}
// 相当于是 like "categoryCode%"
if(StrUtil.isNotEmpty(query.getCategoryCode())) {
String categoryCode = query.getCategoryCode();
boolQueryBuilder.must(QueryBuilders.wildcardQuery("categoryCodeNames", categoryCode+"*"));
}
// 相当于是 like "username%"
if(StrUtil.isNotEmpty(query.getUsername())) {
String username = query.getUsername();
boolQueryBuilder.must(QueryBuilders.wildcardQuery("username", username+"*"));
}
// 相当于是 like "businessCode%"
if(StrUtil.isNotEmpty(query.getBusinessCode())) {
String businessCode = query.getBusinessCode();
boolQueryBuilder.must(QueryBuilders.wildcardQuery("businessCodeNames", businessCode+"*"));
}
// Text自动分词,matchPhrase:模糊匹配且完整
// 相当于: and ( t.appealContent = '%searchKey[0]%' or t.appealContent = '%searchKey[1]%' or...)
String searchKey = query.getHotWords();
if(StrUtil.isNotEmpty(searchKey)) {
// boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("appealContent", searchKey));
BoolQueryBuilder boolQueryBuilder2 = QueryBuilders.boolQuery();
for (String s : searchKey.split(",")) {
boolQueryBuilder2.should(QueryBuilders.matchPhraseQuery("appealContent", s));
}
boolQueryBuilder.must(boolQueryBuilder2);
}
String appealContent = query.getAppealContent();
if(StrUtil.isNotEmpty(appealContent)) {
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("appealContent", appealContent));
}
// 申诉时间 相当于: and t.appealDate between #{startTime} and #{endTime}
if (query.getAppealStartDate() != null && query.getAppealEndDate() != null ){
Date startTime = query.getAppealStartDate();
Date endTime = query.getAppealEndDate();
boolQueryBuilder.must(QueryBuilders.rangeQuery("appealDate").from(startTime).to(endTime).includeUpper(true).includeLower(true));
}
// ES分页搜索
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
//查询条件
.withQuery(boolQueryBuilder)
//分页,page从0开始
.withPageable(PageRequest.of(pageNum, pageSize))
//排序
.withSorts(SortBuilders.fieldSort("appealDate").order(SortOrder.DESC))
//高亮字段显示
.withHighlightFields(
new HighlightBuilder.Field("appealContent").preTags("<em>").postTags("</em>")
)
.build();
SearchHits<AppealDoc> docs = elasticsearchRestTemplate.search(nativeSearchQuery, AppealDoc.class);
部分使用后的感觉
1. must => and
2. should => or
3. 高亮显示的仅是当前字段的某部分数据(存在搜索条件的前后语句而已),并非全部
4.时间如果使用LocalDate/LocatDateTime反正是各种坑,自己转一次Date感觉方便点
5.分页查询时pageNum/curent/pages(当前页)是以0开始的
6.保存和更新是一起的