2. Elasticsearch Repositories 实现 2.1 定义一个ES映射实体org.springframework.boot spring-boot-starter-data-elasticsearch2.3.7.RELEASE
@document(indexName = "yourIndexName", shards = 20)
public class EsExampleEntity implements Serializable {
private static final long serialVersionUID = 2109037559727003184L;
@Id
@Field(type = FieldType.Long)
private Long id;
@Field(type = FieldType.Keyword)
private Long orderNo;
@Field(type = FieldType.Text)
private String name;
@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date gmtCreated;
@MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(type = FieldType.Keyword, suffix = "keyword") })
private String shopName;
}
Text类型会被分词,KeyWord不会被分词,可以用来做聚合相关操作,如果一个字段又想被分词又想用来做聚合就需要使用 @MultiField 来进行指定2.2 查询创建
public interface EsExampleRepository extends ElasticsearchRepository{ }
注意: @Id指定的字段类型要与本处的泛型类型保持一致
① 按照某字段的升序或降序排序,并分页
写法一
FieldSortBuilder statusSort = SortBuilders.fieldSort("status").order(SortOrder.ASC);
FieldSortBuilder gmtModifiedSort = SortBuilders.fieldSort("gmtModified").order(SortOrder.DESC);
Integer current = request.getCurrent();
Integer size = request.getSize();
PageRequest pageRequest = PageRequest.of(current - 1, size);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(mainQuery).withSort(statusSort).withSort(gmtModifiedSort).withSort(SortBuilders.scoreSort()).build();
searchQuery.setPageable(pageRequest);
//设置可以查询超过10000条数据
searchQuery.setTrackTotalHits(true);
Page orderEntities = esCooperationOrderRepository.search(searchQuery);
Long totalElements = orderEntities.getTotalElements();
List content = orderEntities.getContent();
写法二
Sort.Order gmtModified = new Sort.Order(Sort.Direction.DESC, "gmtModified");
Sort.Order topWeight = new Sort.Order(Sort.Direction.valueOf(param.getSortOrder().name()), param.getSortField().name());
Sort orders = Sort.by(topWeight, gmtModified);
PageRequest pageRequest = PageRequest.of(current - 1, size, orders);
// 2、es多条件查询
Page entities = talentGoodsEsRepository.search(getBoolQueryBuilder(param), pageRequest);
② 条件查询
public static void main(String[] args) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//模糊查询
WildcardQueryBuilder spuName = QueryBuilders.wildcardQuery("spuName", "*" + "your searchWord" + "*");
boolQueryBuilder.must(spuName);
//精确查询
boolQueryBuilder.must(QueryBuilders.termQuery("cateNamePath", "your searchWord"));
//范围查询 filter 必须匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档
boolQueryBuilder.filter(QueryBuilders.rangeQuery("salePrice").lte("your word"));
//满足任意一个条件 should
//当使用should查询时,如果包含了must或者filter查询,那么should的查询语句就不是或者的意思了,而是有或者没有都行的含义。
List brandNames = new ArrayList<>();
for (String brandName : brandNames) {
boolQueryBuilder.should(QueryBuilders.termQuery("brandName", brandName));
}
// 参考 https://blog.csdn.net/java_chegnxuyuan/article/details/103025351
boolQueryBuilder.minimumShouldMatch(1);
}
③ 聚合查询
@Autowired
RestHighLevelClient client;
TermsAggregationBuilder liveStartTimeBuilder = AggregationBuilders.terms("liveStartTime").field("liveStartTime");
TermsAggregationBuilder talentNameBuilder = AggregationBuilders.terms("talentName").field("talentName");
TermsAggregationBuilder talentIdBuilder = AggregationBuilders.terms("talentId").field("talentId");
TermsAggregationBuilder liveIdBuilder = AggregationBuilders.terms("liveId").field("liveId");
TermsAggregationBuilder liveNameBuilder = AggregationBuilders.terms("liveName").field("liveName");
ValueCountAggregationBuilder spuCount = AggregationBuilders.count("spuCount").field("spuNo");
ValueCountAggregationBuilder doudianGoodsIdCount = AggregationBuilders.count("doudianGoodsIdCount").field("doudianGoodsId");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
liveStartTimeBuilder.subAggregation(talentIdBuilder);
talentIdBuilder.subAggregation(talentNameBuilder);
talentNameBuilder.subAggregation(liveIdBuilder);
liveIdBuilder.subAggregation(liveNameBuilder);
liveNameBuilder.subAggregation(spuCount).subAggregation(doudianGoodsIdCount);
searchSourceBuilder.query(mainQuery).aggregation(liveStartTimeBuilder).size(0);
SearchRequest searchRequest = new SearchRequest("es_coop_order_entity_index_104");
searchRequest.source(searchSourceBuilder);
client.search(searchRequest, RequestOptions.DEFAULT);
List liveCalendarVoList = Lists.newArrayList();
Aggregations aggregations = searchResponse.getAggregations();
Terms liveStartTimeTerm = aggregations.get("liveStartTime");
for (Terms.Bucket liveStartTimeBucket : liveStartTimeTerm.getBuckets()) {
String liveStartTime = liveStartTimeBucket.getKeyAsString();
Terms talentIdTerm = liveStartTimeBucket.getAggregations().get("talentId");
for (Terms.Bucket talentIdBucket : talentIdTerm.getBuckets()) {
String talentId = talentIdBucket.getKeyAsString();
Terms talentNameTerm = talentIdBucket.getAggregations().get("talentName");
for (Terms.Bucket talentNameBucket : talentNameTerm.getBuckets()) {
String talentName = talentNameBucket.getKeyAsString();
Terms liveIdTerm = talentNameBucket.getAggregations().get("liveId");
for (Terms.Bucket liveIdBucket : liveIdTerm.getBuckets()) {
String liveId = liveIdBucket.getKeyAsString();
Terms liveNameTerm = liveIdBucket.getAggregations().get("liveName");
for (Terms.Bucket liveNameBucket : liveNameTerm.getBuckets()) {
String liveName = liveNameBucket.getKeyAsString();
ParsedValueCount spuCount = liveNameBucket.getAggregations().get("spuCount");
ParsedValueCount doudianGoodsIdCount = liveNameBucket.getAggregations().get("doudianGoodsIdCount");
LiveCalendarVo liveCalendarVo = new LiveCalendarVo();
liveCalendarVo.setLiveDate(liveStartTime);
liveCalendarVo.setTalentId(talentId);
liveCalendarVo.setTalentName(talentName);
liveCalendarVo.setLiveId(liveId);
liveCalendarVo.setLiveName(liveName);
liveCalendarVo.setSpuCount(spuCount.getValue());
liveCalendarVo.setDoudianGoodsIdCount(doudianGoodsIdCount.getValue());
liveCalendarVoList.add(liveCalendarVo);
}
}
}
}
}
//方式二
//聚合条件
TermsAggregationBuilder builder1 = AggregationBuilders.terms("taxonomy").field("taxonomy.keyword");
TermsAggregationBuilder builder2 = AggregationBuilders.terms("year").field("year.keyword");
TermsAggregationBuilder builder = builder1.subAggregation(builder2);
//构建查询
SearchQuery query = new NativeSearchQueryBuilder()
.withQuery(bqb)
.withSort(fsb)
.addAggregation(builder)
.withPageable(pageable)
.build();
ES工具类
package com.befriend.first.base.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; import javax.annotation.Resource; import com.alibaba.fastjson.JSONObject; import com.befriend.common.model.PageVO; import com.befriend.first.base.constant.GlobalConstant; import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.annotations.document; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchScrollHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.core.query.UpdateResponse; import org.springframework.data.elasticsearch.core.query.UpdateResponse.Result; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; @Service public class EsbaseUtils{ public static final String ConTENT = "content"; public static final String NEXT_SCROLL_ID = "nextScrollId"; public static final String TOTAL_COUNT = "totalCount"; public static final String PAGE_VO = "pageVo"; @Resource ElasticsearchRestTemplate template; public Map scrollPage(Integer currentPage, Integer size, QueryBuilder query, String scrollId, String indexName, Class clazz) { IndexCoordinates index = IndexCoordinates.of(indexName); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(query == null ? matchAllQuery() : query) .withPageable(PageRequest.of(currentPage - GlobalConstant.ONE, size)) .build(); Map resultMap = new HashMap<>(GlobalConstant.THREE); List sampleEntities = new ArrayList<>(); long count = template.count(searchQuery, clazz, index); if (StringUtils.isEmpty(scrollId)) { SearchScrollHits scroll = template.searchScrollStart(30000, searchQuery, clazz, index); if (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList())); String nextScrollId = scroll.getScrollId(); resultMap.put(NEXT_SCROLL_ID, nextScrollId); } }else { SearchScrollHits scrollHits = template.searchScrollContinue(scrollId, 30000, clazz, index); if (scrollHits.hasSearchHits()) { sampleEntities.addAll(scrollHits.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList())); String nextScrollId = scrollHits.getScrollId(); resultMap.put(NEXT_SCROLL_ID, nextScrollId); } } resultMap.put(CONTENT, sampleEntities); resultMap.put(TOTAL_COUNT, count); return resultMap; } public Map buildPageVo(Integer currentPage, Integer size, QueryBuilder query, String scrollId, String indexName, Class clazz) { Map finalResMap = new HashMap<>(GlobalConstant.TWO); Map resPageMap = scrollPage(currentPage, size, query, scrollId, indexName, clazz); Long count = (Long)resPageMap.get(TOTAL_COUNT); PageVO pageVO = PageResult.buildResult((List ) resPageMap.get(CONTENT), currentPage, size, count.intValue()); String nextScrollId = (String)resPageMap.get(NEXT_SCROLL_ID); finalResMap.put(PAGE_VO, pageVO); finalResMap.put(NEXT_SCROLL_ID, nextScrollId); if (!pageVO.getHasNext()) { searchScrollClear(nextScrollId); } return finalResMap; } public void searchScrollClear(String scrollId) { template.searchScrollClear(Arrays.asList(scrollId)); } public boolean updateEsEntityById(T esEntity, String id) { Class> aClass = esEntity.getClass(); document annotation = aClass.getAnnotation(document.class); String indexName = annotation.indexName(); Map map = JSONObject.parseObject(JSONObject.toJSonString(esEntity), Map.class); org.springframework.data.elasticsearch.core.document.document document = org.springframework.data.elasticsearch.core.document.document.create(); for (Entry stringObjectEntry : map.entrySet()) { document.put(stringObjectEntry.getKey(), stringObjectEntry.getValue()); } UpdateResponse response = getUpdateResponse(id, indexName, document); return Result.UPDATED.equals(response.getResult()); } public boolean setFieldNullById(String indexName, String fieldName, String id) { org.springframework.data.elasticsearch.core.document.document document = org.springframework.data.elasticsearch.core.document.document.create(); document.put(fieldName, null); UpdateResponse response = getUpdateResponse(id, indexName, document); return Result.UPDATED.equals(response.getResult()); } private UpdateResponse getUpdateResponse(String id, String indexName, org.springframework.data.elasticsearch.core.document.document document) { UpdateQuery build = UpdateQuery.builder(id).withdocument(document).build(); return template.update(build, IndexCoordinates.of(indexName)); } }



