pom
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.15.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.15.1</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.15.1</version>
</dependency>
配置类
@Slf4j
@Component
public class ElasticsearchClient implements DisposableBean {
private RestHighLevelClient client;
@Value("${elasticsearch.esHost}")
private String esHost;
@Value("${elasticsearch.port}")
private Integer port;
@Value("${elasticsearch.username}")
private String username;
@Value("${elasticsearch.password}")
private String password;
@Bean
public RestHighLevelClient restHighLevelClient() {
try {
//需要用户名和密码的认证
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(esHost, port, "http"))
.setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
client = new RestHighLevelClient(restClientBuilder);
log.info("===================elasticsearch restClient 连接成功");
} catch (Exception e) {
log.info("elasticsearch restClient 连接失败", e);
}
return client;
}
@Override
public void destroy() throws Exception {
if (Objects.nonNull(client)) {
client.close();
}
}
}
一些操作
public interface ElasticsearchService {
/**
* 判断索引是否存在
*
* @param index 索引
* @return 存在与否
*/
Boolean existsIndex(String index);
/**
* 创建索引
*
* @param index 索引
*/
void createIndex(String index);
/**
* 插入单条文档
*
* @param index 索引名
* @param id 索引Id
* @param dataMap 文档数据
*/
void insertById(String index, String id, Map<String, Object> dataMap);
/**
* 判断文档是否存在
*
* @param index 索引
* @param id 文档id
*/
Boolean existsDataById(String index, String id);
/**
* 通过id获取文档
*
* @param index 索引名
* @param id 文档id
* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
* @return map集合
*/
Map<String, Object> searchDataById(String index, String id, String fields) throws IOException;
/**
* 根据文档id更新文档
*
* @param index 索引
* @param id 索引id
*/
void updateDataById(String index, String id, Map<String, Object> dataMap);
/**
* 根据文档id删除文档
*
* @param index 索引
* @param id 索引id
*/
void deleteDataById(String index, String id);
/**
* 批量插入文档数据
*
* @param index 索引
* @param dataMap 文档数据
*/
void bulkInsertData(String index, Map<String, Map<String, Object>> dataMap);
/**
* 批量修改文档数据
*
* @param index 索引
* @param dataMap 文档数据
*/
void bulkUpdateData(String index, Map<String, Map<String, Object>> dataMap);
/**
* 批量删除文档数据
*
* @param index 索引
* @param list 文档数据id集合
*/
void bulkDeleteData(String index, List<String> list);
/**
* 根据分词查询
*
* @param index 索引
* @param startTime 开始时间
* @param endTime 结束时间
* @param size 文档大小限制
* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
* @param sortField 排序字段
* @param matchPhrase true时使用,短语精准匹配
* @param highLightField 高亮字段
* @param filterCondition 过滤条件(aaa=111, bbb=222)
* @param nestedType 是否嵌套类型
* @param nestedFilterCondition 嵌套过滤条件(hh_category.category_id=111)
* @return 文档列表
*/
List<Map<String, Object>> searchDataList(String index, Long startTime, Long endTime, Integer size, String fields,
String sortField, Boolean matchPhrase, String highLightField, String filterCondition, Boolean nestedType, String nestedFilterCondition);
/**
* 根据分词查询
*
* @param index 索引
* @param size 文档条数
* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
* @param sortField 排序字段
* @param matchPhrase true时使用,短语精准匹配
* @param filterCondition 过滤条件(aaa=111, bbb=222)
* @param nestedType 是否嵌套类型
* @param nestedFilterCondition 嵌套过滤条件(hh_category.category_id=111)
* @return 文档列表
*/
List<Map<String, Object>> searchDataList(String index, Integer size, String fields,
String sortField, Boolean matchPhrase, String filterCondition, Boolean nestedType, String nestedFilterCondition);
/**
* 根据分词查询,并分页
*
* @param index 索引
* @param currentPage 当前页
* @param pageSize 每页条数
* @param startTime 开始时间
* @param endTime 结束时间
* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
* @param sortField 排序字段
* @param matchPhrase true时使用,短语精准匹配
* @param highLightField 高亮字段
* @param filterCondition 过滤条件(aaa=111, bbb=222)
* @return es分页对象
*/
EsPage searchDataPage(String index, Integer currentPage, Integer pageSize, Long startTime, Long endTime, String fields,
String sortField, Boolean matchPhrase, String highLightField, String filterCondition);
}
具体实现
@Slf4j
@Service("elasticsearchService")
public class ElasticsearchServiceImpl implements ElasticsearchService {
@Resource
private RestHighLevelClient client;
@Override
public Boolean existsIndex(String index) {
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(index);
return client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
return false;
}
@Override
public void createIndex(String index) {
try {
//创建一个索引的请求对象
CreateIndexRequest request = new CreateIndexRequest(index);
//通过client对象去连接ES并执行创建索引
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
log.info("==========插入结果:{}", createIndexResponse.toString());
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
}
@Override
public void insertById(String index, String id, Map<String, Object> dataMap) {
try {
//创建请求
IndexRequest indexRequest = new IndexRequest(index);
//规则 设置文档id
indexRequest.id(id);
indexRequest.source(dataMap);
//将数据放入请求json
//indexRequest.source(JSON.toJSONString(dataMap), XContentType.JSON);
//客户端发送请求
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
log.info("==========插入结果:{}", indexResponse.status());
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
}
@Override
public Boolean existsDataById(String index, String id) {
try {
GetRequest getRequest = new GetRequest(index, id);
//不获取返回的 _source的上下文
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
return client.exists(getRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
return false;
}
@Override
public Map<String, Object> searchDataById(String index, String id, String fields) {
try {
GetRequest getRequest = new GetRequest(index, id);
if (StringUtils.isNotBlank(fields)) {
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, fields.split(","), null);
getRequest.fetchSourceContext(fetchSourceContext);
}
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
return response.getSource();
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
return null;
}
@Override
public void updateDataById(String index, String id, Map<String, Object> dataMap) {
try {
UpdateRequest updateRequest = new UpdateRequest(index, id);
updateRequest.doc(dataMap);
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
log.info("==========更新结果:{}", updateResponse.status());
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
}
@Override
public void deleteDataById(String index, String id) {
try {
DeleteRequest deleteRequest = new DeleteRequest(index, id);
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
log.info("==========删除结果:{}", deleteResponse.status());
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
}
@Override
public void bulkInsertData(String index, Map<String, Map<String, Object>> dataMap) {
try {
BulkRequest bulkRequest = new BulkRequest();
//批处理请求
for (Map.Entry<String, Map<String, Object>> entry : dataMap.entrySet()) {
bulkRequest.add(new IndexRequest(index).id(entry.getKey()).source(entry.getValue()));
}
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (bulkResponse.hasFailures()) {
log.info("==========批量新增失败 index:{}, dataMap:{}, 原因:{}", index, JSONObject.toJSON(dataMap), bulkResponse.buildFailureMessage());
}
} catch (IOException e) {
log.info("==========批量新增报错 index:{}, dataMap:{}, 错误:{}", index, JSONObject.toJSON(dataMap), e);
}
}
@Override
public void bulkUpdateData(String index, Map<String, Map<String, Object>> dataMap) {
try {
BulkRequest bulkRequest = new BulkRequest();
for (Map.Entry<String, Map<String, Object>> entry : dataMap.entrySet()) {
bulkRequest.add(new UpdateRequest(index, entry.getKey()).doc(entry.getValue()));
}
//批处理请求
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (bulkResponse.hasFailures()) {
log.info("==========批量修改失败 index:{}, dataMap:{}, 原因:{}", index, JSONObject.toJSON(dataMap), bulkResponse.buildFailureMessage());
}
} catch (IOException e) {
log.info("==========批量修改报错 index:{}, dataMap:{}, 错误:{}", index, JSONObject.toJSON(dataMap), e);
}
}
@Override
public void bulkDeleteData(String index, List<String> list) {
try {
BulkRequest bulkRequest = new BulkRequest();
//批处理请求
list.forEach(id -> bulkRequest.add(new DeleteRequest(index, id)));
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (bulkResponse.hasFailures()) {
log.info("==========批量删除失败 index:{}, dataMap:{}, 原因:{}", index, JSONObject.toJSON(list), bulkResponse.buildFailureMessage());
}
} catch (IOException e) {
log.info("==========批量删除报错 index:{}, dataMap:{}, 错误:{}", index, JSONObject.toJSON(list), e);
}
}
@Override
public List<Map<String, Object>> searchDataList(String index, Long startTime, Long endTime, Integer size, String fields,
String sortField, Boolean matchPhrase, String highLightField, String filterCondition, Boolean nestedType, String nestedFilterCondition) {
try {
SearchRequest searchRequest = new SearchRequest(index);
//指定dsl,构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//复杂查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//时间范围搜索
if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("timestamp")
.format("epoch_millis")
.from(startTime)
.to(endTime)
.includeLower(true)
.includeUpper(true));
}
//显示的条数
if (Objects.nonNull(size) && size > 0) {
searchSourceBuilder.size(size);
}
//需要显示的字段列表
if (StringUtils.isNotBlank(fields)) {
searchSourceBuilder.fetchSource(fields.split(","), null);
}
//需要排序的字段,倒序
if (StringUtils.isNotBlank(sortField)) {
searchSourceBuilder.sort(SortBuilders.fieldSort(sortField).order(SortOrder.DESC));
}
//搜索的字段 --- 过滤条件
if (StringUtils.isNotBlank(filterCondition)) {
for (String s : filterCondition.split(",")) {
String[] str = s.split("=");
if (str.length > 1) {
if (Objects.equals(matchPhrase, Boolean.TRUE)) {
//短语匹配
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(str[0], str[1]));
} else {
//包含匹配
boolQueryBuilder.must(QueryBuilders.matchQuery(str[0], str[1]));
}
}
}
}
//嵌套类型的筛选(hh_category.category_id=111)
if (nestedType) {
if (StringUtils.isNotBlank(nestedFilterCondition)) {
String[] str = nestedFilterCondition.split("\\.");
String path = str[0];
String[] valueStr = nestedFilterCondition.split("=");
String keyword = valueStr[0];
String value = valueStr[1];
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(path, QueryBuilders.termQuery(keyword, value), ScoreMode.None);
boolQueryBuilder.must(nestedQueryBuilder);
}
}
searchSourceBuilder.query(boolQueryBuilder);
//高亮显示 (aaa=111, bbb=222)
if (StringUtils.isNotBlank(highLightField)) {
//设置高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field(highLightField);
//设置前缀
highlightBuilder.preTags("<span style='color:red' >");
//设置后缀
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
}
searchSourceBuilder.fetchSource(true);
searchRequest.source(searchSourceBuilder);
//执行检索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
long totalRecord = searchResponse.getHits().getTotalHits().value;
log.info("==========totalRecord:{},searchRequest:{}", totalRecord, JSONObject.toJSON(searchRequest));
if (Objects.equals(searchResponse.status().getStatus(), ResultCode.SUCCESS.code)) {
//解析搜索返回对象返回
return setSearchResponse(searchResponse, highLightField);
}
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
return null;
}
@Override
public List<Map<String, Object>> searchDataList(String index, Integer size, String fields, String sortField, Boolean matchPhrase, String filterCondition, Boolean nestedType, String nestedFilterCondition) {
return searchDataList(index, null, null, size, fields, sortField, matchPhrase, null, filterCondition, nestedType, nestedFilterCondition);
}
@Override
public EsPage searchDataPage(String index, Integer currentPage, Integer pageSize, Long startTime, Long endTime, String fields, String sortField,
Boolean matchPhrase, String highLightField, String filterCondition) {
try {
SearchRequest searchRequest = new SearchRequest();
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//复杂查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//时间范围搜索
if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("timestamp")
.format("epoch_millis")
.from(startTime)
.to(endTime)
.includeLower(true)
.includeUpper(true));
}
//需要显示的字段列表
if (StringUtils.isNotBlank(fields)) {
searchSourceBuilder.fetchSource(fields.split(","), null);
}
//需要排序的字段,倒序
if (StringUtils.isNotBlank(sortField)) {
searchSourceBuilder.sort(SortBuilders.fieldSort(sortField).order(SortOrder.DESC));
}
//搜索的字段 --- 过滤条件
if (StringUtils.isNotBlank(filterCondition)) {
for (String s : filterCondition.split(",")) {
String[] str = s.split("=");
if (str.length > 1) {
if (Objects.equals(matchPhrase, Boolean.TRUE)) {
//短语匹配
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(str[0], str[1]));
} else {
//包含匹配
boolQueryBuilder.must(QueryBuilders.matchQuery(str[0], str[1]));
}
}
}
}
//高亮显示 (aaa=111, bbb=222)
if (StringUtils.isNotBlank(highLightField)) {
//设置高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field(highLightField);
//设置前缀
highlightBuilder.preTags("<span style='color:red' >");
//设置后缀
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
}
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.query(boolQueryBuilder);
//分页应用 从第0个开始 pageSize结束
searchSourceBuilder.from(0).size(pageSize);
//设置是否按查询匹配度排序
searchSourceBuilder.explain(true);
searchRequest.source(searchSourceBuilder);
//执行检索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//总数量
long totalRecord = searchResponse.getHits().getTotalHits().value;
log.info("分页查询==========totalRecord:{},searchRequest:{}", totalRecord, JSONObject.toJSON(searchRequest));
if (Objects.equals(searchResponse.status().getStatus(), ResultCode.SUCCESS.code)) {
//解析搜索返回对象
List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highLightField);
// 返回
return new EsPage(currentPage, pageSize, totalRecord, sourceList);
}
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
return null;
}
/**
* 解析搜索的响应对象组装成list返回
*
* @param searchResponse es搜索响应对象
* @param highLightField 高亮字段
* @return 集合
*/
private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highLightField) {
List<Map<String, Object>> sourceList = new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder();
for (SearchHit searchHit : searchResponse.getHits().getHits()) {
if (StringUtils.isNotBlank(highLightField)) {
//获取高亮的字段,获取高亮字段对应的值
HighlightField highlightField = searchHit.getHighlightFields().get(highLightField);
if (Objects.nonNull(highlightField)) {
Text[] text = highlightField.fragments();
if (Objects.nonNull(text)) {
for (Text str : text) {
stringBuilder.append(str.string());
}
//遍历 高亮结果集,覆盖 正常结果集
searchHit.getSourceAsMap().put(highLightField, stringBuilder.toString());
log.info("==========遍历高亮结果集,覆盖正常结果集" + searchHit.getSourceAsMap());
}
}
}
sourceList.add(searchHit.getSourceAsMap());
}
return sourceList;
}
}
自定义的查询结构
@Slf4j
@Service("searchService")
public class SearchServiceImpl implements SearchService {
@Resource
private RestHighLevelClient client;
private String[] highlightFiledArr = new String[]{
"name",
"name.iks",
// "name.fpy",
"name.spy",
"contact",
// "contact.fpy",
"contact.iks",
"contact.spy",
"mobile",
"mobile.iks",
"system_no"
// ,"remake","telephone",
// "create_user.email","create_user.mobile","create_user.real_name",
// "department_job","fax_number",
// "hh_attribution_record.former_org_name","hh_attribution_record.former_owner_name",
// "hh_clue_follow_record.company_name","hh_clue_follow_record.content",
// "hh_task_record.address", "hh_task_record.next_content", "hh_task_record.remark", "hh_task_record.title"
};
@Override
public EsPage searchPublicCluesSale(PublicCluesSaleSearchParam saleSearchParam) {
try {
if (Objects.isNull(saleSearchParam)) {
return null;
}
//分页应用 从第0个开始 pageSize结束
Integer page = saleSearchParam.getPage();
Integer pageSize = saleSearchParam.getPageSize();
if (Objects.isNull(page) && Objects.isNull(pageSize)) {
return null;
}
//搜索请求 设置索引
SearchRequest searchRequest = new SearchRequest("hh_sale_clue");
//构建搜索条件 DSL语句
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//复杂查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
String keyword = saleSearchParam.getWord();
log.info("=========keyword:{}", keyword);
if (StringUtil.isNotBlank(keyword)) {
//关键词 全模糊 must 对应多字段匹配
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, highlightFiledArr));
}
//查询可用线索
boolQueryBuilder.filter(QueryBuilders.termQuery("state", DataStatus.OPEN.status));
Integer status = saleSearchParam.getStatus();
if (Objects.nonNull(status)) {
//客户状态精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("status", status));
}
Integer source = saleSearchParam.getSource();
if (Objects.nonNull(source)) {
//客户星级精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("source", source));
}
Integer ownerUid = saleSearchParam.getOwnerUid();
if (Objects.nonNull(ownerUid)) {
//前归属人员精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("owner_uid", ownerUid));
}
Integer role = saleSearchParam.getRole();
if (Objects.nonNull(role)) {
//角色精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("role", role));
}
Integer sex = saleSearchParam.getSex();
if (Objects.nonNull(sex)) {
//尊称精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("sex", sex));
}
Integer groupDepartmentId = saleSearchParam.getGroupDepartmentId();
if (Objects.nonNull(groupDepartmentId)) {
//所属部门精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("group_department_id", groupDepartmentId));
}
Integer createUid = saleSearchParam.getCreateUid();
if (Objects.nonNull(createUid)) {
//创建人员精确匹配
boolQueryBuilder.filter(QueryBuilders.termQuery("create_uid", createUid));
}
//最后跟进时间范围搜索
String lastFollowTimeStart = saleSearchParam.getLastFollowTimeStart();
String lastFollowTimeEnd = saleSearchParam.getLastFollowTimeEnd();
if (StringUtil.isNotBlank(lastFollowTimeStart) && StringUtil.isNotBlank(lastFollowTimeEnd)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("hh_task_record.last_follow_time")
.from(lastFollowTimeStart)
.to(lastFollowTimeEnd)
.includeLower(true)
.includeUpper(true));
}
//下次跟进时间范围搜索
String nextFollowTimeStart = saleSearchParam.getNextFollowTimeStart();
String nextFollowTimeEnd = saleSearchParam.getNextFollowTimeEnd();
if (StringUtil.isNotBlank(nextFollowTimeStart) && StringUtil.isNotBlank(nextFollowTimeEnd)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("hh_task_record.next_follow_time")
.from(nextFollowTimeStart)
.to(nextFollowTimeEnd)
.includeLower(true)
.includeUpper(true));
}
//创建时间范围搜索
String createTimeStart = saleSearchParam.getCreateTimeStart();
String createTimeEnd = saleSearchParam.getCreateTimeEnd();
if (StringUtils.isNotBlank(createTimeStart) && StringUtils.isNotBlank(createTimeEnd)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("create_time")
.from(createTimeStart)
.to(createTimeEnd)
.includeLower(true)
.includeUpper(true));
}
//修改时间范围搜索
String modifyTimeStart = saleSearchParam.getModifyTimeStart();
String modifyTimeEnd = saleSearchParam.getModifyTimeEnd();
if (StringUtils.isNotBlank(nextFollowTimeStart) && StringUtils.isNotBlank(nextFollowTimeEnd)) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("modify_time")
.from(modifyTimeStart)
.to(modifyTimeEnd)
.includeLower(true)
.includeUpper(true));
}
//最后联系时间范围搜索
// String lastContactTimeStart = saleSearchParam.getLastContactTimeStart();
// String lastContactTimeEnd = saleSearchParam.getLastContactTimeEnd();
// if (StringUtils.isNotBlank(lastContactTimeStart) && StringUtils.isNotBlank(lastContactTimeEnd)) {
// boolQueryBuilder.must(QueryBuilders.rangeQuery("modify_time")
// .from(lastContactTimeStart)
// .to(lastContactTimeEnd)
// .includeLower(true)
// .includeUpper(true));
// }
//首字母筛选 支持首字母、全拼搜索
String initials = saleSearchParam.getInitials();
if (StringUtil.isNotBlank(initials)) {
boolQueryBuilder.must(QueryBuilders.matchQuery("name.spy", initials));
}
//需要排序的字段 和 升降序
String sortField = saleSearchParam.getSortField();
Integer orderBy = saleSearchParam.getOrderBy();
if (StringUtil.isNotBlank(sortField)) {
if (Objects.equals(orderBy, 1)) {
searchSourceBuilder.sort(SortBuilders.fieldSort(sortField).order(SortOrder.DESC));
} else if (Objects.equals(orderBy, 2)) {
searchSourceBuilder.sort(SortBuilders.fieldSort(sortField).order(SortOrder.ASC));
}
}
//需要显示的字段列表
List<Field> fieldList = saleSearchParam.getFields();
if (Objects.nonNull(fieldList) && !fieldList.isEmpty()) {
String[] fieldArray = fieldList.stream().map(Field::getKey).toArray(String[]::new);
searchSourceBuilder.fetchSource(fieldArray, null);
}
//客户分类搜索
//Integer classify = saleSearchParam.getClassify();
//if (Objects.equals(classify, 1)) {
// boolQueryBuilder.filter(QueryBuilders.termQuery("owner_uid", getcurrentUid()));
//}
//搜索的字段 --- 已选条件
List<Field> selectCondition = saleSearchParam.getSelectCondition();
if (Objects.nonNull(selectCondition) && !selectCondition.isEmpty()) {
selectCondition.forEach(field -> {
String key = field.getKey();
Object value = field.getValue();
if (Objects.equals(key, "initial")) {
//首字母
boolQueryBuilder.must(QueryBuilders.matchQuery(key + ".spy", value));
} else {
boolQueryBuilder.filter(QueryBuilders.termQuery(key, value));
}
});
}
int from = (page - 1) * pageSize;
searchSourceBuilder.from(from).size(pageSize);
//高亮显示 (aaa=111)
Boolean highlightField = saleSearchParam.getHighlightField();
if (Objects.nonNull(highlightField)) {
if (highlightField) {
//生成高亮查询器
HighlightBuilder highlightBuilder = new HighlightBuilder();
//设置高亮字段
for (String s : highlightFiledArr) {
highlightBuilder.field(s);
}
//设置前缀
highlightBuilder.preTags("<span style='color:red' >");
//设置后缀
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
//HighlightBuilder highlightBuilder = new HighlightBuilder();
//highlightBuilder.field("name.iks").preTags("<span style=\"color:red\">").postTags("</span>");
//searchSourceBuilder.highlighter(highlightBuilder);
}
}
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
// searchSourceBuilder.fetchSource(publicClueFiledArr,new String[]{});
//指定查询条件
searchSourceBuilder.query(boolQueryBuilder);
//设置是否按查询匹配度排序
searchSourceBuilder.explain(true);
//查询条件构建器
searchRequest.source(searchSourceBuilder);
//执行检索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
log.info("=========searchResponse:{}", searchResponse.toString());
//总数量
long totalRecord = searchResponse.getHits().getTotalHits().value;
if (Objects.equals(searchResponse.status().getStatus(), ResultCode.SUCCESS.code)) {
//解析搜索返回对象
List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightFiledArr);
// 返回
return new EsPage(page, pageSize, totalRecord, sourceList);
}
} catch (IOException e) {
log.info("=========e:{}", Throwables.getStackTraceAsString(e));
}
//搜索请求
return null;
}
/**
* 解析搜索的响应对象组装成list返回
*
* @param searchResponse es搜索响应对象
* @param highLightField 高亮字段
* @return 集合
*/
private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String[] highLightField) {
List<Map<String, Object>> sourceList = new ArrayList<>();
for (SearchHit searchHit : searchResponse.getHits().getHits()) {
for (String s : highLightField) {
//获取高亮的字段,获取高亮字段对应的值
HighlightField highlightField = searchHit.getHighlightFields().get(s);
if (Objects.nonNull(highlightField)) {
Text[] text = highlightField.fragments();
if (Objects.nonNull(text)) {
StringBuilder stringBuilder = new StringBuilder();
for (Text str : text) {
stringBuilder.append(str.string());
}
//遍历 高亮结果集,覆盖 正常结果集
searchHit.getSourceAsMap().put(s, stringBuilder.toString());
log.info("==========遍历高亮结果集,覆盖正常结果集" + searchHit.getSourceAsMap());
}
}
}
sourceList.add(searchHit.getSourceAsMap());
}
return sourceList;
}
}
对于结果集的一些处理
@Slf4j
public class ESResultUtil {
/**
* 下划线
*/
public static final char UNDERLINE = '_';
/**
* 结尾类型
*/
public static final String[] ENDS_SUFFIX = new String[]{".iks", ".spy", ".fpy"};
/**
* map 转 java对象
*
* @param sourceList
* @param t
* @param <T>
* @return
*/
public static <T> List<T> mapToEntity(List<Map<String, Object>> sourceList, Class<T> t) {
List<T> list = new ArrayList<>();
if(sourceList.isEmpty()) {
return list;
}
Map<String, Object> objectMap = new HashMap<>();
Map<String, Object> objectMap1 = new HashMap<>();
for (Map<String, Object> stringObjectMap : sourceList) {
objectMap.clear();
objectMap1.clear();
stringObjectMap.forEach((s, o) -> {
if (Objects.nonNull(o) && o instanceof Map) {
//关联表的数据
Map<String, Object> map = (Map) o;
map.forEach((s1, o1) -> {
String s2 = underlineToCamel(s1);
objectMap.put(s2, o1);
});
} else {
if (StringUtil.isNotBlank(s) && (
s.endsWith(ENDS_SUFFIX[0])
|| s.endsWith(ENDS_SUFFIX[1])
|| s.endsWith(ENDS_SUFFIX[2]))) {
//以 .iks .spy .fpy 结尾的数据。
String s2 = underlineToCamel(s);
String substring = s2.substring(0, s2.length() - 4);
if(Objects.isNull(objectMap1.get(substring))){
objectMap1.put(substring, o);
}
} else {
//基础表的数据
String s1 = underlineToCamel(s);
objectMap.put(s1, o);
}
}
});
objectMap1.forEach((s, o) -> objectMap.put(s,objectMap1.get(s)));
T t1 = new JSONObject(objectMap).toJavaObject(t);
list.add(t1);
}
return list;
}
/**
* 将"_"转成驼峰(user_id:userId)
*
* @param param user_id
* @return userId
*/
public static String underlineToCamel(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (c == UNDERLINE) {
if (++i < len) {
sb.append(Character.toUpperCase(param.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
}
文章来源地址https://www.toymoban.com/news/detail-516377.html
文章来源:https://www.toymoban.com/news/detail-516377.html
到了这里,关于ES JAVA API的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!