赞
踩
- @Slf4j
- @Component
- public class EsTemplate {
-
- @Autowired
- private RestHighLevelClient client;
-
- private static final String TIMESTAMP = "timestamp";
-
- /**
- * 创建索引(默认分片数为5和副本数为1)
- *
- * @param indexName
- * @param esMapTypeClass
- * @throws IOException
- */
- public boolean createIndex(String indexName, Class<? extends IESMappingType> esMapTypeClass) throws IOException {
- if (checkIndexExists(indexName)) {
- log.error("\"index={}\"索引已经存在!", indexName);
- return false;
- }
- CreateIndexRequest request = new CreateIndexRequest(indexName);
- XContentBuilder builder = buildXContentBuilder(indexName, esMapTypeClass);
- request.mapping(esMapTypeClass.getSimpleName(), builder);
-
- CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
- // 指示是否所有节点都已确认请求
- boolean acknowledged = response.isAcknowledged();
- // 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
- boolean shardsAcknowledged = response.isShardsAcknowledged();
- if (acknowledged || shardsAcknowledged) {
- log.info("创建索引成功!索引名称为{}", indexName);
- return true;
- }
-
- log.error("创建索引失败");
- return false;
-
- }
-
- /**
- * 创建索引
- *
- * @param index
- * @throws IOException
- */
- public boolean createIndex(String index) throws IOException {
- if (checkIndexExists(index)) {
- log.error("\"index={}\"索引已存在!", index);
- return false;
- }
- CreateIndexRequest request = new CreateIndexRequest(index);
- CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
- boolean acknowledged = response.isAcknowledged();
- boolean shardsAcknowledged = response.isShardsAcknowledged();
- if (acknowledged || shardsAcknowledged) {
- log.info("创建索引成功!索引名称为{}", index);
- return true;
- } else {
- log.error("创建索引失败");
- return false;
- }
- }
-
- /**
- * 创建索引(传入参数:分片数、副本数)
- *
- * @param indexName
- * @param shards
- * @param replicas
- * @throws IOException
- */
- public boolean createIndex(String indexName, int shards, int replicas) throws IOException {
- if (checkIndexExists(indexName)) {
- log.error("\"index={}\"索引已存在!", indexName);
- return false;
- }
- Settings.Builder builder = Settings.builder().put("index.number_of_shards", shards).put("index.number_of_replicas", replicas);
- CreateIndexRequest request = new CreateIndexRequest(indexName).settings(builder);
- // request.mapping(TYPE, generateBuilder());
- CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
- if (response.isAcknowledged() || response.isShardsAcknowledged()) {
- log.info("创建索引成功!索引名称为{}", indexName);
- return true;
- } else {
- log.error("创建索引失败");
- return false;
- }
- }
-
- /**
- * 删除索引
- *
- * @param indexName
- * @throws IOException
- */
- public Boolean deleteIndex(String indexName) throws IOException {
- try {
- AcknowledgedResponse response = client.indices().delete(new DeleteIndexRequest(indexName), RequestOptions.DEFAULT);
- if (response.isAcknowledged()) {
- log.info("{} 索引删除成功!", indexName);
- return true;
- }
- } catch (ElasticsearchException ex) {
- if (ex.status() == RestStatus.NOT_FOUND) {
- log.error("{} 索引名不存在", indexName);
- return false;
- }
- log.error("删除失败!");
- }
- return false;
- }
-
-
- /**
- * 判断索引是否存在
- *
- * @param indexName
- * @return
- * @throws IOException
- */
- public boolean checkIndexExists(String indexName) {
- GetIndexRequest request = new GetIndexRequest().indices(indexName);
- try {
- return client.indices().exists(request, RequestOptions.DEFAULT);
- } catch (IOException e) {
- log.error("判断索引是否存在,操作异常!");
- }
- return false;
- }
-
-
- /**
- * 开启索引
- *
- * @param indexName
- * @throws IOException
- */
- public void openIndex(String indexName) throws IOException {
- if (!checkIndexExists(indexName)) {
- log.error("索引不存在!");
- return;
- }
- OpenIndexRequest request = new OpenIndexRequest(indexName);
- OpenIndexResponse response = client.indices().open(request, RequestOptions.DEFAULT);
- if (response.isAcknowledged() || response.isShardsAcknowledged()) {
- log.info("{} 索引开启成功!", indexName);
- }
- }
-
- /**
- * 关闭索引
- *
- * @param indexName
- * @throws IOException
- */
- public void closeIndex(String indexName) throws IOException {
- if (!checkIndexExists(indexName)) {
- log.error("索引不存在!");
- return;
- }
- CloseIndexRequest request = new CloseIndexRequest(indexName);
- AcknowledgedResponse response = client.indices().close(request, RequestOptions.DEFAULT);
- if (response.isAcknowledged()) {
- log.info("{} 索引已关闭!", indexName);
- }
- }
-
-
- /**
- * 查找文档
- *
- * @param index
- * @param type
- * @param id
- * @return
- * @throws IOException
- */
- public Map<String, Object> getDocument(String index, String type, String id) throws IOException {
- Map<String, Object> resultMap = new HashMap<>();
- GetRequest request = new GetRequest(index, type, id);
- // 实时(否)
- request.realtime(false);
- // 检索之前执行刷新(是)
- request.refresh(true);
-
- GetResponse response = null;
- try {
- response = client.get(request, RequestOptions.DEFAULT);
- } catch (ElasticsearchException e) {
- if (e.status() == RestStatus.NOT_FOUND) {
- log.error("文档未找到,请检查参数!");
- }
- if (e.status() == RestStatus.CONFLICT) {
- log.error("版本冲突!");
- }
- log.error("查找失败!");
- }
-
- if (Objects.nonNull(response)) {
- if (response.isExists()) { // 文档存在
- resultMap = response.getSourceAsMap();
- } else {
- // 处理未找到文档的方案。 请注意,虽然返回的响应具有404状态代码,但仍返回有效的GetResponse而不是抛出异常。
- // 此时此类响应不持有任何源文档,并且其isExists方法返回false。
- log.error("文档不存在!");
- }
- }
- return resultMap;
- }
-
- /**
- * 判断文档是否存在
- * @param
- * @return true:存在 false:不存在
- * @author hucm
- * @since 2021/5/31
- */
- public boolean existDoc(String index, String type, String id) throws IOException {
- GetRequest request = new GetRequest(index, type,id);
- // 不需要获取source内容
- request.fetchSourceContext(new FetchSourceContext(false));
- return client.exists(request, RequestOptions.DEFAULT);
- }
-
- /**
- * 删除文档
- *
- * @param indexName
- * @param typeName
- * @param docId
- * @throws IOException
- */
- public void deleteDocument(String indexName, String typeName, String docId) throws IOException {
- DeleteRequest request = new DeleteRequest(indexName, typeName, docId);
- DeleteResponse response = null;
- try {
- response = client.delete(request, RequestOptions.DEFAULT);
- } catch (ElasticsearchException e) {
- if (e.status() == RestStatus.CONFLICT) {
- log.error("版本冲突!");
- }
- log.error("删除失败!");
- }
- if (Objects.nonNull(response)) {
- if (response.getResult() == DocWriteResponse.Result.NOT_FOUND) {
- log.error("不存在该文档,请检查参数!");
- }
- log.info("文档已删除!");
- ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
- if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
- log.error("部分分片副本未处理");
- }
- if (shardInfo.getFailed() > 0) {
- for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
- String reason = failure.reason();
- log.error("失败原因:{}", reason);
- }
- }
- }
- }
-
- /**
- * 通过一个脚本语句(如:"ctx._source.posttime=\"2018-09-18\"")更新文档
- * 针对单个字段更新或object类型字段更新
- * @param index
- * @param type
- * @param id
- * @param script
- */
- public void updateDocByScript(String index, String type, String id, String script) throws IOException {
- Script inline = new Script(script);
- UpdateRequest request = new UpdateRequest(index, type, id).script(inline);
- try {
- UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
- if (response.getResult() == DocWriteResponse.Result.UPDATED) {
- //log.info("文档更新成功!");
- } else if (response.getResult() == DocWriteResponse.Result.DELETED) {
- log.error("\"index={},type={},id={}\"的文档已被删除,无法更新!", response.getIndex(), response.getType(), response.getId());
- } else if (response.getResult() == DocWriteResponse.Result.NOOP) {
- log.error("操作没有被执行!");
- }
-
- ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
- if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
- log.error("部分分片副本未处理");
- }
- if (shardInfo.getFailed() > 0) {
- for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
- String reason = failure.reason();
- log.error("未处理原因:{}", reason);
- }
- }
- } catch (ElasticsearchException e) {
- if (e.status() == RestStatus.NOT_FOUND) {
- log.error("不存在这个文档,请检查参数!");
- } else if (e.status() == RestStatus.CONFLICT) {
- log.error("版本冲突异常!");
- }
- log.error("更新失败!:{},脚本:{},id:{}",e.getMessage(),script,id);
- }
- }
-
- /**
- * 通过一个脚本语句(针对于object和nested数据类型字段更新)更新文档
- * @param index
- * @param type
- * @param id
- * @param script
- * @param params
- * @throws IOException
- */
- public void updateDocByScript(String index, String type, String id, String script,Map<String, Object> params) throws IOException {
- Script inline = new Script(ScriptType.INLINE,Script.DEFAULT_SCRIPT_LANG,script,params);
- UpdateRequest request = new UpdateRequest(index, type, id).script(inline);
- try {
- UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
- if (response.getResult() == DocWriteResponse.Result.UPDATED) {
- //log.info("文档更新成功!");
- } else if (response.getResult() == DocWriteResponse.Result.DELETED) {
- log.error("\"index={},type={},id={}\"的文档已被删除,无法更新!", response.getIndex(), response.getType(), response.getId());
- } else if (response.getResult() == DocWriteResponse.Result.NOOP) {
- log.error("操作没有被执行!");
- }
-
- ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
- if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
- log.error("部分分片副本未处理");
- }
- if (shardInfo.getFailed() > 0) {
- for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
- String reason = failure.reason();
- log.error("未处理原因:{}", reason);
- }
- }
- } catch (ElasticsearchException e) {
- if (e.status() == RestStatus.NOT_FOUND) {
- log.error("不存在这个文档,请检查参数!");
- } else if (e.status() == RestStatus.CONFLICT) {
- log.error("版本冲突异常!");
- }
- log.error("更新失败!:{},脚本:{},id:{}",e.getMessage(),script,id);
- }
- }
-
- /**
- * 批量增加文档
- *
- * @param indexName
- * @param typeName
- * @param esMappingTypes 添加的文档列表
- * @throws IOException
- */
- public List<String> bulkAdd(String indexName, String typeName, List<? extends IESMappingType> esMappingTypes) throws IOException {
- List<String> failureList = new ArrayList<>();
- BulkRequest bulkRequest = new BulkRequest();
- if (CollectionUtils.isNotEmpty(esMappingTypes)) {
- for (IESMappingType mappingType : esMappingTypes) {
- IndexRequest request = new IndexRequest(indexName, typeName, mappingType.generateDocId()).source(JSON.toJSONString(mappingType), XContentType.JSON);
- bulkRequest.add(request);
- }
- }
- // 超时时间(2分钟)
- bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
- // 刷新策略
- bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
-
- if (bulkRequest.numberOfActions() == 0) {
- log.error("参数错误,批量增加操作失败!");
- return new ArrayList<>();
- }
- BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
- // 全部操作成功
- if (!bulkResponse.hasFailures()) {
- // log.info("批量增加操作成功!");
- } else {
- for (BulkItemResponse bulkItemResponse : bulkResponse) {
- if (bulkItemResponse.isFailed()) {
- BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
- log.error("\"index={}, type={}, id={}\"的文档增加失败!", failure.getIndex(), failure.getType(), failure.getId());
- log.error("增加失败详情: {}", failure.getMessage());
- failureList.add(failure.getId());
- log.error("新增失败的货品id:{}",failureList);
- return failureList;
- } else {
- // log.info("\"index={}, type={}, id={}\"的文档增加成功!", bulkItemResponse.getIndex(), bulkItemResponse.getType(), bulkItemResponse.getId());
- }
- }
- }
- return new ArrayList<>();
- }
-
- /**
- * 根据条件删除es数据
- *
- * @param indexName 索引名称
- * @param bigBoolQueryBuilder
- * @return 删除条数
- * @author shixiaorui
- * @date 2020/8/31 18:27
- */
- public Long delByEsQuery(String indexName, BoolQueryBuilder bigBoolQueryBuilder) {
- DeleteByQueryRequest request =
- new DeleteByQueryRequest(indexName);
- request.setQuery(bigBoolQueryBuilder);
- try {
- BulkByScrollResponse bulkResponse =
- client.deleteByQuery(request, RequestOptions.DEFAULT);
- return bulkResponse.getDeleted();
- } catch (ElasticsearchException e) {
- if (e.status() == RestStatus.CONFLICT) {
- log.error("版本冲突!");
- }
- log.error("删除失败!:{}", e.getMessage());
- } catch (IOException ioExp) {
- log.error("删除失败:{}", ioExp.getMessage());
- }
- return 0L;
-
- }
-
- /**
- * 批量更新文档
- *
- * @param indexName
- * @param typeName
- * @param esMappingTypes
- * @throws IOException
- */
- public List<String> bulkUpdate(String indexName, String typeName, List<? extends IESMappingType> esMappingTypes) throws IOException {
- List<String> failureList = new ArrayList<>();
- BulkRequest bulkRequest = new BulkRequest();
- if (CollectionUtils.isNotEmpty(esMappingTypes)) {
- for (IESMappingType mappingType : esMappingTypes) {
- UpdateRequest request=new UpdateRequest(indexName, typeName, mappingType.generateDocId())
- .doc(JSON.toJSONString(mappingType), XContentType.JSON);
- // true,表明如果文档不存在,则新更新的文档内容作为新的内容插入文档,
- //这个和scriptedUpsert的区别是:更新文档的两种不同方式,有的使用doc方法更新有的使用脚本更新
- request.docAsUpsert(true);
-
- // 是否将文档内容作为结果返回,默认是禁止的
- request.fetchSource(false);
- bulkRequest.add(request);
- }
- }
-
-
-
- if (bulkRequest.numberOfActions() == 0) {
- log.error("参数错误,批量更新操作失败!");
- return new ArrayList<>();
- }
- bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
- bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
- BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
- if (!bulkResponse.hasFailures()) {
- // log.info("批量更新操作成功!");
- } else {
- for (BulkItemResponse bulkItemResponse : bulkResponse) {
- if (bulkItemResponse.isFailed()) {
- BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
- log.error("\"index={}, type={}, id={}\"的文档更新失败!", failure.getIndex(), failure.getType(), failure.getId());
- log.error("更新失败详情: {}", failure.getMessage());
- failureList.add(failure.getId());
- log.error("更新失败的货品id: {}", failureList);
- return failureList;
- }/* else {
- log.info("\"index={}, type={}, id={}\"的文档更新成功!", bulkItemResponse.getIndex(), bulkItemResponse.getType(), bulkItemResponse.getId());
- }*/
- }
- }
- return failureList;
- }
-
- /**
- * 批量删除文档
- *
- * @param indexName
- * @param typeName
- * @param docIds
- * @throws IOException
- */
- public boolean bulkDelete(String indexName, String typeName, List<String> docIds) throws IOException {
-
- BulkRequest bulkRequest = new BulkRequest();
- if (CollectionUtils.isNotEmpty(docIds)) {
- for (String docId : docIds) {
- DeleteRequest request = new DeleteRequest(indexName, typeName, docId);
- bulkRequest.add(request);
- }
- }
- if (bulkRequest.numberOfActions() == 0) {
- log.error("操作失败,请检查参数!");
- return false;
- }
- bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
- bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
- BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
- if (!bulkResponse.hasFailures()) {
- log.info("批量删除操作成功!");
- return true;
- } else {
- for (BulkItemResponse bulkItemResponse : bulkResponse) {
- if (bulkItemResponse.isFailed()) {
- BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
- log.error("\"index={}, type={}, id={}\"的文档删除失败!", failure.getIndex(), failure.getType(), failure.getId());
- log.error("删除失败详情: {}", failure.getMessage());
- return false;
- }
- }
- return false;
- }
- }
-
- /**
- * 批量查找文档
- *
- * @param indexName
- * @return
- * @throws IOException
- */
- public List<Map<String, Object>> multiGet(String indexName, String typeName, List<String> docIds) throws IOException {
- List<Map<String, Object>> resultList = new ArrayList<>();
- MultiGetRequest request = new MultiGetRequest();
- if (CollectionUtils.isNotEmpty(docIds)) {
- for (String docId : docIds) {
- request.add(new MultiGetRequest.Item(indexName, typeName, docId));
- }
- }
- request.realtime(false);
- request.refresh(true);
- MultiGetResponse response = client.mget(request, RequestOptions.DEFAULT);
- List<Map<String, Object>> list = parseMGetResponse(response);
- if (!list.isEmpty()) {
- resultList.addAll(list);
- }
- return resultList;
- }
-
- private List<Map<String, Object>> parseMGetResponse(MultiGetResponse response) {
- List<Map<String, Object>> list = new ArrayList<>();
- MultiGetItemResponse[] responses = response.getResponses();
- for (MultiGetItemResponse item : responses) {
- GetResponse getResponse = item.getResponse();
- if (Objects.nonNull(getResponse)) {
- if (!getResponse.isExists()) {
- log.error("\"index={}, type={}, id={}\"的文档查找失败,请检查参数!", getResponse.getIndex(), getResponse.getType(), getResponse.getId());
- } else {
- list.add(getResponse.getSourceAsMap());
- }
- } else {
- MultiGetResponse.Failure failure = item.getFailure();
- ElasticsearchException e = (ElasticsearchException) failure.getFailure();
- if (e.status() == RestStatus.NOT_FOUND) {
- log.error("\"index={}, type={}, id={}\"的文档不存在!", failure.getIndex(), failure.getType(), failure.getId());
- } else if (e.status() == RestStatus.CONFLICT) {
- log.error("\"index={}, type={}, id={}\"的文档版本冲突!", failure.getIndex(), failure.getType(), failure.getId());
- }
- }
- }
- return list;
- }
-
- /**
- * 根据条件搜索日志内容(参数level和messageKey不能同时为空)
- *
- * @param level 日志级别,可以为空
- * @param messageKey 日志信息关键字,可以为空
- * @param startTime 日志起始时间,可以为空
- * @param endTime 日志结束时间,可以为空
- * @param size 返回记录数,可以为空,默认最大返回10条。该值必须小于10000,如果超过10000请使用 {@link #queryAllByConditions}
- * @return
- * @throws IOException
- */
- public List<Map<String, Object>> queryByConditions(String indexName, String typeName, String level, String messageKey, Long startTime, Long endTime, Integer size) throws IOException {
- List<Map<String, Object>> resultList = new ArrayList<>();
- if (StringUtils.isBlank(level) && StringUtils.isBlank(messageKey)) {
- log.error("参数level(日志级别)和messageKey(日志信息关键字)不能同时为空!");
- return resultList;
- }
-
- QueryBuilder query = generateQuery(level, messageKey, startTime, endTime);
- FieldSortBuilder order = SortBuilders.fieldSort(TIMESTAMP).order(SortOrder.DESC);
- SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
- searchBuilder.timeout(TimeValue.timeValueMinutes(2L));
- searchBuilder.query(query);
- searchBuilder.sort(order);
- if (Objects.nonNull(size)) {
- searchBuilder.size(size);
- }
-
- SearchRequest request = new SearchRequest(indexName).types(typeName);
- request.source(searchBuilder);
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- int failedShards = response.getFailedShards();
- if (failedShards > 0) {
- log.error("部分分片副本处理失败!");
- for (ShardSearchFailure failure : response.getShardFailures()) {
- String reason = failure.reason();
- log.error("分片处理失败原因:{}", reason);
- }
- }
- List<Map<String, Object>> list = parseSearchResponse(response);
- if (!list.isEmpty()) {
- resultList.addAll(list);
- }
- return resultList;
- }
-
- private QueryBuilder generateQuery(String level, String messageKey, Long startTime, Long endTime) {
- // term query(检索level)
- TermQueryBuilder levelQuery = null;
- if (StringUtils.isNotBlank(level)) {
- levelQuery = QueryBuilders.termQuery("level", level.toLowerCase());
- }
- // match query(检索message)
- MatchQueryBuilder messageQuery = null;
- if (StringUtils.isNotBlank(messageKey)) {
- messageQuery = QueryBuilders.matchQuery("name", messageKey);
- }
- // range query(检索timestamp)
- RangeQueryBuilder timeQuery = QueryBuilders.rangeQuery(TIMESTAMP);
- timeQuery.format("epoch_millis");
- if (Objects.isNull(startTime)) {
- if (Objects.isNull(endTime)) {
- timeQuery = null;
- } else {
- timeQuery.lte(endTime);
- }
- } else {
- if (Objects.isNull(endTime)) {
- timeQuery.gte(startTime);
- } else {
- timeQuery.gte(startTime).lte(endTime);
- }
- }
- // 将上述三个query组合
- BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
- if (Objects.nonNull(levelQuery)) {
- boolQuery.must(levelQuery);
- }
- if (Objects.nonNull(messageQuery)) {
- boolQuery.must(messageQuery);
- }
- if (Objects.nonNull(timeQuery)) {
- boolQuery.must(timeQuery);
- }
- return boolQuery;
- }
-
- private List<Map<String, Object>> parseSearchResponse(SearchResponse response) {
- List<Map<String, Object>> resultList = new ArrayList<>();
- SearchHit[] hits = response.getHits().getHits();
- for (SearchHit hit : hits) {
- resultList.add(hit.getSourceAsMap());
- }
- return resultList;
- }
-
- /**
- * 查询所有文档id
- *
- * @return
- */
- public List<String> queryAllIdByIndexName(String indexName, String typeName) throws IOException {
- List<String> resultList = new ArrayList<>();
- SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
- searchBuilder.size(500);
-
- // 初始化 scroll 上下文
- SearchRequest request = new SearchRequest(indexName).types(typeName);
- final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
- request.source(searchBuilder).scroll(scroll);
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- String scrollId = response.getScrollId();
- SearchHit[] searchHits = response.getHits().getHits();
- // 把第一次scroll的数据添加到结果List中
- for (SearchHit searchHit : searchHits) {
- resultList.add(searchHit.getId());
- }
- // 通过传递scrollId循环取出所有相关文档
- while (searchHits.length > 0) {
- SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
- scrollRequest.scroll(scroll);
- response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
- scrollId = response.getScrollId();
- searchHits = response.getHits().getHits();
- // 循环添加剩下的数据
- for (SearchHit searchHit : searchHits) {
- resultList.add(searchHit.getId());
- }
- }
- // 清理 scroll 上下文
- ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
- clearScrollRequest.addScrollId(scrollId);
- client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
- return resultList;
- }
-
- /**
- * 根据条件,搜索全部符合的记录(参数level和messageKey不能同时为空)
- *
- * @param level 日志级别,可以为空
- * @param messageKey 日志信息关键字,可以为空
- * @param startTime 日志起始时间,可以为空
- * @param endTime 日志结束时间,可以为空
- * @return
- */
- public List<Map<String, Object>> queryAllByConditions(String indexName, String typeName, String level, String messageKey, Long startTime, Long endTime) throws IOException {
- List<Map<String, Object>> resultList = new ArrayList<>();
- if (StringUtils.isBlank(level) && StringUtils.isBlank(messageKey)) {
- log.error("参数level(日志级别)和messageKey(日志信息关键字)不能同时为空!");
- return resultList;
- }
-
- QueryBuilder query = generateQuery(level, messageKey, startTime, endTime);
- FieldSortBuilder order = SortBuilders.fieldSort(TIMESTAMP).order(SortOrder.DESC);
- SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
- searchBuilder.query(query).sort(order);
- searchBuilder.size(500);
-
- // 初始化 scroll 上下文
- SearchRequest request = new SearchRequest(indexName).types(typeName);
- final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
- request.source(searchBuilder).scroll(scroll);
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- String scrollId = response.getScrollId();
- SearchHit[] searchHits = response.getHits().getHits();
- // 把第一次scroll的数据添加到结果List中
- for (SearchHit searchHit : searchHits) {
- resultList.add(searchHit.getSourceAsMap());
- }
- // 通过传递scrollId循环取出所有相关文档
- while (searchHits != null && searchHits.length > 0) {
- SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
- scrollRequest.scroll(scroll);
- response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
- scrollId = response.getScrollId();
- searchHits = response.getHits().getHits();
- // 循环添加剩下的数据
- for (SearchHit searchHit : searchHits) {
- resultList.add(searchHit.getSourceAsMap());
- }
- }
- // 清理 scroll 上下文
- ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
- clearScrollRequest.addScrollId(scrollId);
- client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
- return resultList;
- }
-
- /**
- * 根据条件做分页查询(参数level和messageKey不能同时为空)
- *
- * @param level 日志级别,可以为空
- * @param messageKey 日志信息关键字,可以为空
- * @param startTime 日志起始时间,可以为空
- * @param endTime 日志结束时间,可以为空
- * @param pageNum 当前页码,可以为空(默认设为1)
- * @param pageSize 页记录数,可以为空(默认设为10)
- * @return
- * @throws IOException
- */
- public SearchPageBean<Map<String, Object>> queryPageByConditions(String indexName, String typeName, String level, String messageKey, Long startTime, Long endTime, Integer pageNum, Integer pageSize) throws IOException {
- if (StringUtils.isBlank(level) && StringUtils.isBlank(messageKey)) {
- log.error("参数level(日志级别)、messageKey(日志信息关键字)不能同时为空!");
- return null;
- }
-
- if (Objects.isNull(pageNum)) {
- pageNum = 1;
- }
- if (Objects.isNull(pageSize)) {
- pageSize = 10;
- }
- QueryBuilder query = generateQuery(level, messageKey, startTime, endTime);
- FieldSortBuilder order = SortBuilders.fieldSort(TIMESTAMP).order(SortOrder.DESC);
- SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
- searchBuilder.timeout(TimeValue.timeValueMinutes(2L));
- searchBuilder.query(query);
- searchBuilder.sort(order);
- searchBuilder.from(pageNum - 1).size(pageSize);
-
- SearchRequest request = new SearchRequest(indexName).types(typeName);
- request.source(searchBuilder);
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- SearchHits hits = response.getHits();
- int totalRecord = (int) hits.getTotalHits();
- List<Map<String, Object>> results = new ArrayList<>();
- for (SearchHit hit : hits.getHits()) {
- results.add(hit.getSourceAsMap());
- }
-
- SearchPageBean<Map<String, Object>> page = new SearchPageBean<>();
- page.setPageNo(pageNum);
- page.setPageSize(pageSize);
- page.setTotalPages(totalRecord);
- page.setData(results);
- return page;
- }
-
-
- /**
- * 通用查询
- * 复杂查询可以自定义实现RestHighLevelClient
- *
- * @param indexName 索引
- * @param eSMappingType 返回的对象类型
- * @param searchSourceBuilder 查询条件
- * @param <T> 泛型
- * @return pageResult
- * @author zhangxh
- * @since 2019/07/04
- */
- public <T> PageResult<T> search(String indexName, Class<T> eSMappingType, SearchSourceBuilder searchSourceBuilder) {
- if (eSMappingType == null) {
- throw new IllegalArgumentException("eSMappingType can not be null");
- }
- if (indexName == null) {
- throw new ServiceException("indexName 不能为空");
- }
-
- SearchRequest searchRequest = new SearchRequest()
- .indices(indexName)
- .types(eSMappingType.getSimpleName())
- .source(searchSourceBuilder);
-
- try {
- SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
- SearchHits hits = search.getHits();
- SearchHit[] hitsArray = hits.getHits();
- PageResult<T> pageResult = new PageResult<>();
- pageResult.setRecordCount((int) hits.getTotalHits());
- List<T> list = new ArrayList<>();
- for (SearchHit hit : hitsArray) {
- list.add(JsonHelper.parseBean(hit.getSourceAsString(), eSMappingType));
- }
- pageResult.setResult(list);
- // log.info("es查询语句:{}" , searchSourceBuilder.toString());
- return pageResult;
- } catch (Exception e) {
- log.error("查询文档:{},失败:{}", indexName, e.getMessage());
- e.printStackTrace();
- }
- return new PageResult<>();
- }
-
-
- public <T> PageResult<T> searchMore(String indexName, Class<T> eSMappingType, SearchSourceBuilder searchSourceBuilder) {
- if (eSMappingType == null) {
- throw new IllegalArgumentException("eSMappingType can not be null");
- }
- if (indexName == null) {
- throw new ServiceException("indexName 不能为空");
- }
-
- searchSourceBuilder.from(0).size(10000);
-
- SearchRequest searchRequest = new SearchRequest()
- .indices(indexName)
- .types(eSMappingType.getSimpleName())
- .source(searchSourceBuilder);
-
- try {
- SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
- SearchHits hits = search.getHits();
- SearchHit[] hitsArray = hits.getHits();
- PageResult<T> pageResult = new PageResult<>();
- pageResult.setRecordCount((int) hits.getTotalHits());
- List<T> list = new ArrayList<>();
- for (SearchHit hit : hitsArray) {
- list.add(JsonHelper.parseBean(hit.getSourceAsString(), eSMappingType));
- }
- pageResult.setResult(list);
- // log.info("es查询语句:{}" , searchSourceBuilder.toString());
- return pageResult;
- } catch (Exception e) {
- log.error("查询文档:{},失败:{}", indexName, e.getMessage());
- e.printStackTrace();
- }
- return new PageResult<>();
- }
-
-
- private XContentBuilder generateBuilder() throws IOException {
- XContentBuilder builder = XContentFactory.jsonBuilder();
- builder.startObject();
- builder.startObject("properties");
- builder.startObject("message");
- builder.field("type", "text");
- // 为message字段,设置分词器为 ik_smart(最粗粒度)
- builder.field("analyzer", "ik_smart");
- builder.endObject();
- builder.startObject(TIMESTAMP);
- builder.field("type", "date");
- // 设置 日志时间的格式为 毫秒数的long类型
- builder.field("format", "epoch_millis");
- builder.endObject();
- builder.endObject();
- builder.endObject();
- return builder;
- }
-
-
-
-
- /**
- * 根据IESMappingType 的实现类,生成创建mappingType的 XContentBuilder
- *
- * @param esMapTypeClass
- * @return
- * @throws IOException
- */
- public XContentBuilder buildXContentBuilder(String index, Class<? extends IESMappingType> esMapTypeClass) throws IOException {
- XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
-
- // 处理对象属性类型
- dealObj(builder, esMapTypeClass);
- builder.endObject();
- return builder;
- }
-
- /**
- * 根据对象的es属性注解判断是否进行属性处理
- *
- * @param builder
- * @param esMapTypeClass
- * @throws IOException
- */
- private void dealObj(XContentBuilder builder, Class<? extends IESMappingType> esMapTypeClass) throws IOException {
- // 子属性放到该索引下
- builder.startObject("properties");
- for (Field field : esMapTypeClass.getDeclaredFields()) {
- ESField fieldProp = field.getAnnotation(ESField.class);
- if (fieldProp != null) {
- dealField(builder, field, fieldProp);
- }
- }
-
- //判断对象是否有 @Suggestable 注解,有则添加 suggest 字段
- EnableSuggest suggest = esMapTypeClass.getAnnotation(EnableSuggest.class);
- if (suggest != null) {
- String analyzer = suggest.analyzerType().name();
- String suggestName = suggest.suggestName();
- builder.startObject(suggestName)
- .field("type", "completion")
- .field("index_analyzer", analyzer)
- .field("search_analyzer", analyzer)
- .field("payloads", "true")
- .field("preserve_position_increments", false)
- .field("preserve_separators", false)
- .endObject();
- }
- builder.endObject();
- }
-
-
-
-
- /**
- * 处理对象的属性类型
- *
- * @param builder
- * @param field 属性
- * @param fieldProp 属性注解信息
- * @throws IOException
- */
- private void dealField(XContentBuilder builder, Field field, ESField fieldProp) throws IOException {
- try {
- if (List.class.isAssignableFrom(field.getType()) || field.getType().isArray()) {
- //list 类型的 嵌套类型和对象数组
- builder.startObject(field.getName());// 这里如果是startArray就会有问题.
- if (fieldProp.fieldType() == ESFieldType.NESTED) {
- //嵌套类型(要查询对象信息)
- builder.field("type", ESFieldType.NESTED.getTypeValue());
- }else{
- //对象数组(只是保存对象信息)
- builder.field("type", ESFieldType.OBJECT.getTypeValue());
- }
-
- String className = "";
- Type fc = field.getGenericType();
- if (fc instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) fc;
- className = pt.getActualTypeArguments()[0].toString().replace("class ", "");
- } else if (field.getType().isArray()) {
- className = field.getGenericType().toString().replace("class [L", "")
- .replace("/", ".").replace(";", "");
- }
-
- Class clazz = Class.forName(className);
-
- if (IESMappingType.class.isAssignableFrom(clazz) || clazz.getAnnotation(ESDocObject.class) != null) {
- dealObj(builder, clazz);
- } else if (clazz.isPrimitive() || isSimpleType(clazz)) {
- builder.field("type", ESFieldType.STRING.getTypeValue())
- .field("index", ESAnalyzer.not_analyzed.name()).field("store", fieldProp.isStore());
- }
- builder.endObject();
- } else if (Map.class.isAssignableFrom(field.getType())) {
- System.out.println("Map:" + field.getName());
- } else {
- // 处理简单对象
- if (isSimpleType(field.getType())) {
- dealSimpleObjField(builder, field.getName(), fieldProp);
- return;
- }
-
- // 如果是复杂的组合类型,继承于ESMapTypeI,则进行递归处理
- String className = field.getGenericType().toString().replace("class ", "");
- Class complexClazz = Class.forName(className);
- if (IESMappingType.class.isAssignableFrom(complexClazz)) {
- builder.startObject(field.getName());
- if (fieldProp.fieldType() == ESFieldType.NESTED) {
- builder.field("type", ESFieldType.NESTED.getTypeValue());
- }
- dealObj(builder, complexClazz);
- builder.endObject();
- }
- }
- } catch (Exception e) {
- log.error("创建mapping出错...", e);
- }
- }
-
- /**
- * 判断是否是简单的对象.
- *
- * @param cls
- * @return
- */
- private static boolean isSimpleType(Class cls) {
- if (cls == String.class || cls == Integer.class || cls == BigDecimal.class || cls == Date.class || cls == int.class || cls == long.class || cls == Long.class) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * 处理对象类型的域值,处理已经是最简单对象的field
- */
- public void dealSimpleObjField(XContentBuilder mapbuilder, String fieldName, ESField eSMapType) throws IOException {
-
- mapbuilder.startObject(fieldName).field("store", eSMapType.isStore()).field("type", eSMapType.fieldType().getTypeValue());
- ESAnalyzer esAnalyzer = eSMapType.analyzerType();
- if (esAnalyzer != ESAnalyzer.not_analyzed) {
- if (esAnalyzer == ESAnalyzer.analyzed) {
- mapbuilder.field("index", "true");
- } else {
- mapbuilder.field("index", "true").
- field("search_analyzer", esAnalyzer.name())
- .field("analyzer", esAnalyzer.name());
- }
-
- } else if (esAnalyzer == ESAnalyzer.not_analyzed) {
- mapbuilder.field("index", "false");
- }
- mapbuilder.endObject();
-
- }
-
- /**
- * es聚合分组求和
- *
- * @param indexName 索引名称
- * @param groupKey 分组的key
- * @param sumKey 求和的key
- * @return Map
- * @author shixiaorui
- * @date 2020/11/12 10:29
- */
- public Map<String, Long> groupKeySum(String indexName, String eSMappingTypeName, SearchSourceBuilder searchSourceBuilder, String groupKey, String sumKey) {
- try {
- SearchRequest searchRequest = new SearchRequest()
- .indices(indexName)
- .types(eSMappingTypeName)
- .source(searchSourceBuilder);
-
- String aggName = groupKey + "_key";//分组字段别名
- String aggField = sumKey + "_key";//求和字段别名
-
-
- //分组groupKey,求和sumKey
- TermsAggregationBuilder field = AggregationBuilders.terms(aggName).field(groupKey);
- field.subAggregation(AggregationBuilders.sum(aggField).field(sumKey));
- searchSourceBuilder.aggregation(field);
-
- searchRequest.source(searchSourceBuilder);
- //执行查询
- SearchResponse response = client.search(searchRequest);
-
- //获取搜索的文档结果
- Map<String, Aggregation> aggMap = response.getAggregations().getAsMap();
- Terms gradeTerms = (Terms) aggMap.get(aggName);
-
- Map<String, Long> returnMap = new HashMap<>();
- Map<String, Long> valueResult = new LinkedHashMap<>();
- if(null!=gradeTerms.getBuckets()&&gradeTerms.getBuckets().size()>0){
- for (Terms.Bucket bucket : gradeTerms.getBuckets()) {
- double num = ((Sum) bucket.getAggregations().get(aggField)).getValue();
- returnMap.put(bucket.getKeyAsString(), new Double(num).longValue());
- }
-
- //排序
- returnMap.entrySet().stream()
- .sorted(Map.Entry
- .comparingByValue(Comparator.reverseOrder()))
- .forEachOrdered(b->valueResult.put(b.getKey(), b.getValue()));
- return valueResult;
- }
- return new HashMap<>();
-
- } catch (Exception ex) {
- ex.printStackTrace();
- return null;
- }
- }
-
-
-
- /**
- * 查询,包含下钻聚合数据
- *
- * @param indexName 索引
- * @param eSMappingType 返回的对象类型
- * @param searchSourceBuilder 查询条件
- * @return pageResult
- * @author hucm
- * @since 2021/08/17
- */
- public IndexSearchResponse searchGroupBy(String indexName, Class eSMappingType, SearchSourceBuilder searchSourceBuilder, MallEsSearchFormDTO form) {
- if (eSMappingType == null) {
- throw new IllegalArgumentException("eSMappingType can not be null");
- }
- if (indexName == null) {
- throw new ServiceException("indexName 不能为空");
- }
-
- SearchRequest searchRequest = new SearchRequest()
- .indices(indexName)
- .types(eSMappingType.getSimpleName())
- .source(searchSourceBuilder);
-
- try {
- SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
- SearchHits hits = search.getHits();
- SearchHit[] hitsArray = hits.getHits();
- // 封装返回结果
- IndexSearchResponse response = new IndexSearchResponse();
- // 放入源数据
- response.setOriginHits(hits);
-
- List<String> sources = new ArrayList<>();
- for (SearchHit hit : hits.getHits()) {
- sources.add(hit.getSourceAsString());
- }
- response.putReslutData(sources);
- // 聚合结果
- response.putResultAggs(agg2Map(search.getAggregations()));
- // 总数据
- response.setPageNum(form.getPageNo());
- response.setPageSize(form.getPageSize());
- response.setTotalCount((int) hits.getTotalHits());
- return response;
- } catch (Exception e) {
- log.error("查询文档:{},失败:{}", indexName, e.getMessage());
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * 处理一个聚合对象数据{@link Aggregations}
- *
- * @param aggregations
- * @return Map{key:一个聚合的名称,value:聚合后的桶数据}
- */
- public Map<String, Object> agg2Map(Aggregations aggregations) {
- Map<String, Object> resultMap = new HashMap<>();
- if (aggregations == null) {
- return resultMap;
- }
- for (Aggregation aggregation : aggregations) {
-
- resultMap.put(aggregation.getName(), dealOneAggregation(aggregation));
- }
- return resultMap;
- }
-
- /**
- * 处理一个聚合对象
- *
- * @param aggregation {@link Aggregation}
- * @return 如果只有一个桶数据, 则返回对象, 如果有多个桶数据, 则返回数组
- */
- public Object dealOneAggregation(Aggregation aggregation) {
- if (aggregation instanceof ParsedStringTerms) {
- Collection<? extends Terms.Bucket> buckets = ((ParsedStringTerms) aggregation).getBuckets();
- return dealBunkets(buckets);
- } else if (aggregation instanceof ParsedDoubleTerms) {
- Collection<? extends Terms.Bucket> buckets = ((ParsedDoubleTerms) aggregation).getBuckets();
- return dealBunkets(buckets);
- } else if (aggregation instanceof ParsedLongTerms) {
- Collection<? extends Terms.Bucket> buckets = ((ParsedLongTerms) aggregation).getBuckets();
- return dealBunkets(buckets);
- } else if (aggregation instanceof UnmappedTerms) {
- Collection<? extends Terms.Bucket> buckets = ((UnmappedTerms) aggregation).getBuckets();
- return dealBunkets(buckets);
- } else if (aggregation instanceof ParsedNested) {
- Aggregations aggregations = ((ParsedNested) aggregation).getAggregations();
- return agg2list(aggregations);
- } else if (aggregation instanceof ParsedAvg) {
- return aggregation.getName();
- } else {
- throw new IllegalArgumentException("未知聚合类型,不可处理");
- }
- }
-
- /**
- * 处理一个聚合下边的一个或多个桶数据
- *
- * @param buckets
- * @return 如果有一个桶, 那么就返回一个对象, 而不是列表 如果有多个桶,则返回列表 如果没有值,则返回一个空对象
- */
- public Object dealBunkets(Collection<? extends Terms.Bucket> buckets) {
- List<Object> list = new ArrayList<>();
- for (Terms.Bucket bucket : buckets) {
- list.add(dealOneBunket(bucket));
- }
- return list.isEmpty() ? new Object() : list.size() == 1 ? list.get(0) : list;
- }
-
- /**
- * 处理一个bunkey
- *
- * @param bucket
- * @return 如果没有子查询返回bunkey中的值[String]
- * 如果有子查询,返回一个对应的map对象[HashMap]--{key:bunketKey,value:子查询返回的map}
- */
- public Object dealOneBunket(Terms.Bucket bucket) {
- Object params = null;
- if (bucket.getAggregations().iterator().hasNext()) {
- params = agg2list(bucket.getAggregations());
- }
- if (params == null) {
- return bucket.getKey();// 没有子查询
- } else if (params instanceof List) {
- List<Object> resultList = (List) params;
- if (resultList.size() == 1) {
- return resultList.get(0);
- } else if (resultList.size() > 1) {
- Map<String, Object> resultMap = new HashMap<>();
- resultMap.put(bucket.getKey().toString(), resultList);
- return resultMap;
- } else {
- return resultList;
- }
- } else {
- // 没有子查询
- Map<String, Object> resultMap = new HashMap<>();
- resultMap.put(bucket.getKey().toString(), params);
- return resultMap;
- }
- }
-
- /**
- * 处理子聚合的方法
- *
- * @param aggregations
- * @return
- * @author of1081
- */
- public Object agg2list(Aggregations aggregations) {
- List<Object> resultList = new ArrayList<>();
- for (Aggregation aggregation : aggregations) {
- if (!(aggregation instanceof InternalAvg)) {
- resultList.add(dealOneAggregation(aggregation));
- }
- }
- return resultList.isEmpty() ? new Object() : resultList.size() == 1 ? resultList.get(0) : resultList;
- }
-
- }
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import org.elasticsearch.search.SearchHits;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- /**
- * @author liangck
- * @version 1.0
- * @since 15/8/12 11:02
- */
- public class IndexSearchResponse {
-
- /**
- * result中的聚合结果
- **/
- private static final String AGGS_RESULT = "aggs";
- /**
- * result中的查询结果数据
- **/
- private static final String DATA_RESULT = "data";
-
- /**
- * 结果总数
- */
- private int totalCount;
-
- /**
- * 当前页码
- */
- private int pageNum;
-
- /**
- * 每页数据条数
- */
- private int pageSize;
-
- /**
- * 数据结果集
- */
- private Map<String, Object> result = new HashMap<>();
-
- /**
- * 查询的源结果
- */
- private SearchHits originHits;
-
- /**
- * 无参数构造器
- */
- public IndexSearchResponse() {
- }
-
- /**
- * 根据结果纪录总数,当前查询页码,每页数据条数 构造返回结果集
- *
- * @param totalCount 查询到的数据总条数
- * @param pageNum 当前页码
- * @param pageSize 每页数据条数
- */
- public IndexSearchResponse(int totalCount, int pageNum, int pageSize) {
- this(totalCount, pageNum, pageSize, null);
- }
-
- /**
- * 根据结果纪录总数,当前查询页码,每页数据条数 构造返回结果集
- *
- * @param totalCount 查询到的数据总条数
- * @param pageNum 当前页码
- * @param pageSize 每页数据条数
- * @param result 数据集
- */
- public IndexSearchResponse(int totalCount, int pageNum, int pageSize,
- Map<String, Object> result) {
- this.totalCount = totalCount;
- this.pageNum = pageNum;
- this.pageSize = pageSize;
- this.result = result;
- }
-
- /**
- * 放入聚合结果
- *
- * @param aggResult 聚合结果
- */
- public void putResultAggs(Object aggResult) {
- result.put(AGGS_RESULT, aggResult);
- }
-
- /**
- * 放入查询结果数据
- *
- * @param data 查询结果数据
- */
- public void putReslutData(Object data) {
- result.put(DATA_RESULT, data);
- }
-
- /**
- * 获取聚合结果
- *
- * @return
- */
- public Object getResultAgg() {
- return result.get(AGGS_RESULT);
- }
-
- /**
- * 获取查询结果数据
- *
- * @return
- */
- public Object getResultData() {
- return result.get(DATA_RESULT);
- }
-
- /**
- * 返回结果数据的json字符串,方便进行反序列化
- *
- * @return
- */
- public String getResultDataJsonString() {
- return (result.get(DATA_RESULT) == null) ? null
- : JSON.toJSONString(result.get(DATA_RESULT))
- .replace("[\"{", "[{").replace("}\"]", "}]")
- .replace("\\", "").replace("}\"", "}")
- .replace("\"{", "{");
- }
-
- /**
- * 返回指定类型的查询数据结果
- *
- * @param clazz
- * @param <T>
- * @return
- */
- public <T> List<T> getResultDataBeans(Class<T> clazz) {
- return getResultDataJsonString() == null ? new ArrayList() : JSONArray
- .parseArray(getResultDataJsonString(), clazz);
- }
-
- public int getTotalCount() {
- return totalCount;
- }
-
- public void setTotalCount(int totalCount) {
- this.totalCount = totalCount;
- }
-
- public int getPageNum() {
- return pageNum;
- }
-
- public void setPageNum(int pageNum) {
- this.pageNum = pageNum;
- }
-
- public int getPageSize() {
- return pageSize;
- }
-
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
-
- public Map<String, Object> getResult() {
- return result;
- }
-
- public void setResult(Map<String, Object> result) {
- this.result = result;
- }
-
- public SearchHits getOriginHits() {
- return originHits;
- }
-
- public void setOriginHits(SearchHits originHits) {
- this.originHits = originHits;
- }
-
- @Override
- public String toString() {
- return "[{totalCount:" + totalCount + "},{pageNum:" + pageNum
- + "},{pageSize:" + pageSize + "}],{result:" + result + "}]";
- }
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface ESDocObject {
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface ESField {
- /**
- * 字段名称
- *
- * @return
- */
- public String fieldName() default "";
-
- /**
- * 字段类型,默认为string
- *
- * @return
- */
- public ESFieldType fieldType() default ESFieldType.TEXT;
-
- /**
- * 分词器,默认不进行分词
- *
- * @return
- */
- ESAnalyzer analyzerType() default ESAnalyzer.not_analyzed;
-
- /**
- * 是否存储,默认为是
- *
- * @return
- */
- public boolean isStore() default true;
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface EnableSuggest {
-
- String suggestName() default "suggest";
-
- /**
- * 分词器
- *
- * @return {@link ESAnalyzer}
- */
- ESAnalyzer analyzerType() default ESAnalyzer.ik_smart;
-
- }
- /**
- * <p>
- * es 文档数据类型,所有定义为es文档的bean 必须实现该接口
- * </p>
- *
- * @author liangck
- * @version 1.0
- * @since 15/8/9 12:20
- */
- public interface IESMappingType {
-
- /**
- * 生成文档ID
- * @return 文档ID
- */
- String generateDocId();
-
- /**
- * 返回该文档对象进行索引的field, 用于反射调用生成MapType
- *
- * @return {@link Field}
- */
- public Field[] foundTypeField();
- }
- /**
- * of1081_yxd on 2015/1/7. Description: ES 内置分析器
- */
- public enum ESAnalyzer {
-
- /**
- * standard tokenizer, standard filter, lower case filter, stop filter
- */
- standard(),
-
- /**
- * lower case tokenizer
- */
- simple(),
- /**
- * ik_max_word
- */
- ik_max_word(),
-
- /**
- * ik_max_word
- */
- ik_smart(),
-
- /**
- * lower case tokenizer, stop filter
- */
- stop(),
-
- /**
- * 不分词,内容整体作为一个token(not_analyzed)
- */
- keyword(),
-
- /**
- * 正则表达式分词,默认匹配\W+
- */
- whitespace(),
-
- /**
- * 各种语言
- */
- // lang(),
-
- /**
- * standard tokenizer, standard filter, lower case filter, stop filter,
- * snowball filter
- */
- snowball(),
-
- /**
- * 不进行索引
- */
- not_analyzed(),
-
- /**
- * 进行索引
- */
- analyzed(),
-
-
- /**
- * Ansj搜索条件分词
- */
- ansj_query(),
-
- /**
- * Ansj索引文档分词
- */
- ansj_index(),
-
- /**
- * Ansj智能分词,即索引文档时使用ansj_index,搜索文档时使用ansj_query分词
- */
- ansj_auto(),
-
-
- /**
- * 一个Tokenizer, 零个或多个Token Filter, 零个或多个Char Filter
- */
- ESAnalyzer() {
- }
- }
-
- /**
- * of1081_yxd on 2015/1/6. Description:索引-映射结构中字段类型.
- */
- public enum ESFieldType {
-
- /**
- * string 数据类型
- */
- STRING("string"),
-
- /**
- * string 数据类型
- */
- TEXT("text"),
-
- /**
- * keyword 全局查询文本类型
- */
- KEYWORD("keyword"),
-
- /**
- * double 数据类型
- */
- DOUBLE("double"),
- /**
- * nested类型
- */
- NESTED("nested"),
-
- /**
- * object类型
- */
- OBJECT("object"),
-
- /**
- * boolean 数据类型
- */
- BOOLEAN("boolean"),
-
- /**
- * integer 数据类型
- */
- INTEGER("integer"),
-
- /**
- * date 数据类型
- */
- DATE("date"),
-
- /**
- * long 数据类型
- */
- LONG("long");
-
- /**
- * ES中数据类型标识
- */
- private String typeValue;
-
- ESFieldType(String typeValue) {
- this.typeValue = typeValue;
- }
-
- public String getTypeValue() {
- return typeValue;
- }
- }
- @Slf4j
- public class IkAnalzyerUtil {
-
- /**
- * 使用IK分词器 进行分词
- *
- * @param phrase
- * @return
- */
- public static List<String> segmentPhraseByIk(String phrase) {
- if (phrase == null)
- throw new NullPointerException("待分词短语不能为空!");
-
- // 构建IK分词器,使用smart分词模式
- Analyzer analyzer = null;
- try {
-
-
- analyzer = new IKAnalyzer(true);
- } catch (Exception e) {
- // e.printStackTrace();\
- log.error("use IK has error {}", e.getLocalizedMessage());
- return new ArrayList<>();
- }
-
- //TODO ik分詞有坑
- return segmentPhraseByAnalyzer(analyzer, phrase);
- }
-
- /**
- * 标准分词器分词 ,中文会被切分为单字
- *
- * @param phrase
- * @return
- */
- public static List<String> segmentPhraseByStandardAnalyzer(String phrase) {
- Analyzer analyzer = new StandardAnalyzer();
- return segmentPhraseByAnalyzer(analyzer, phrase);
- }
-
- /**
- * 指定分词器分词
- *
- * @param analyzer
- * @param phrase
- * @return
- */
- public static List<String> segmentPhraseByAnalyzer(Analyzer analyzer, String phrase) {
-
- // 获取Lucene的TokenStream对象
- TokenStream ts = null;
-
- //最终返回的分词结果
- List<String> terms = new ArrayList<>();
- try {
- ts = analyzer.tokenStream("keywords", new StringReader(phrase));
- // 获取词元位置属性
- OffsetAttribute offset = ts.addAttribute(OffsetAttribute.class);
- // 获取词元文本属性
- CharTermAttribute term = ts.addAttribute(CharTermAttribute.class);
- // 获取词元文本属性
- TypeAttribute type = ts.addAttribute(TypeAttribute.class);
-
- // 重置TokenStream(重置StringReader)
- ts.reset();
- // 迭代获取分词结果
- while (ts.incrementToken()) {
- log.debug(offset.startOffset() + " - " + offset.endOffset() + " : " + term.toString() + " | " + type.type());
- // System.out.println(offset.startOffset() + " - " + offset.endOffset() + " : " + term.toString() + " | " + type.type());
- //放入词
- terms.add(term.toString());
- }
- // 关闭TokenStream(关闭StringReader)
- ts.end();
-
- } catch (Exception e) {
- log.error(e.getLocalizedMessage(), e);
- return new ArrayList<>();
- } finally {
- // 释放TokenStream的所有资源
- if (ts != null) {
- try {
- ts.close();
- } catch (IOException e) {
- log.error(e.getLocalizedMessage(), e);
- }
- }
- }
- //放入该短语
- // terms.add(phrase);
- return terms;
- }
-
- }
- /**
- * 查询条件封装
- * @param form
- * @return
- */
- private SearchSourceBuilder searchMallEsCondition(MallEsSearchFormDTO form) {
- BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
-
- // 关键词查询[商品名称/货品名称/品牌名称]
- // if (StringUtils.isNotBlank(form.getKeywords())) {
- // List<String> analyzedWords = IkAnalzyerUtil.segmentPhraseByIk(form.getKeywords());
- // for (String word : analyzedWords) {
- // boolQuery.must(queryStringQuery(String.format("*%s*", word.trim())).field("goodsName").field("goodsInfoName"));
- // }
- // }
- if (StringUtils.isNotBlank(form.getKeywords())) {
- boolQuery.must(QueryBuilders.multiMatchQuery(form.getKeywords(),"goodsInfoName","goodsName").operator(Operator.AND));
- }
- // 指定货品编码参数组合查询
- // List<String> goodsInfoItemNos = form.getGoodsInfoItemNos();
- // if (!ListHelper.isObjectNullOrEmpty(goodsInfoItemNos) && goodsInfoItemNos.size() > 0) {
- // BoolQueryBuilder includeBoolQuery = QueryBuilders.boolQuery();
- // for (String goodsInfoItemNo : goodsInfoItemNos) {
- // BoolQueryBuilder inBoolQuery = QueryBuilders.boolQuery();
- // inBoolQuery.must(matchQuery("goodsInfoItemNo", goodsInfoItemNo));
- // includeBoolQuery.should(inBoolQuery);
- // }
- // boolQuery.must(includeBoolQuery);
- // }
-
- //商品名称模糊查询
- if (StringUtils.isNotEmpty(form.getGoodsName())) {
- //boolQuery.must(queryStringQuery(String.format("*%s*", form.getGoodsName())).field("goodsName"));
- boolQuery.must(queryStringQuery(String.format("\"*%s*\" OR *%s*", form.getGoodsName(), form.getGoodsName())).field("goodsName"));
- }
-
- //货品名称模糊查询
- if (StringUtils.isNotEmpty(form.getGoodsInfoName())) {
- //boolQuery.must(queryStringQuery(String.format("*%s*", form.getGoodsInfoName())).field("goodsInfoName"));
- boolQuery.must(queryStringQuery(String.format("\"*%s*\" OR *%s*", form.getGoodsInfoName(), form.getGoodsInfoName())).field("goodsInfoName"));
- }
-
- if (!StringHelper.isNullOrEmpty(form.getPromotionFlag())&&"1".equals(form.getPromotionFlag())){
- boolQuery.must(QueryBuilders.nestedQuery("marketingActivityList",QueryBuilders.existsQuery("marketingActivityList"), ScoreMode.None));
- searchSourceBuilder.sort("activityGoodsSort",SortOrder.ASC);
- }
-
- if (!StringHelper.isNullOrEmpty(form.getPromotionGrade())){
- boolQuery.must(QueryBuilders.nestedQuery("marketingActivityList",QueryBuilders.queryStringQuery(String.format("*%s*", form.getPromotionGrade())).field("marketingActivityList.marketJoinGrade"), ScoreMode.None));
- }
-
- if (!StringHelper.isNullOrEmpty(form.getShowChannel())){
- boolQuery.must(QueryBuilders.nestedQuery("marketingActivityList",QueryBuilders.queryStringQuery(String.format("*%s*", form.getShowChannel())).field("marketingActivityList.showChannel"), ScoreMode.None));
- }
-
- if (!StringHelper.isNullOrEmpty(form.getShowStock())&&"0".equals(form.getShowStock())){
-
- RangeQueryBuilder goodsInfoStock = rangeQuery("goodsInfoStock")
- .gt(0);
- boolQuery.must(goodsInfoStock);
- }
-
- /******查询是否上架商品********/
- if (StringUtil.isNotEmptyOrWhiteSpace(form.getGoodsInfoAdded())) {
- /****-1的时候表示全部****/
- if (!form.getGoodsInfoAdded().equals("-1")) {
- //默认查询是要在列表展示的
- if (form.getKeywords() != null) {
- // 搜索是否上架的商品
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", form.getGoodsInfoAdded()));
- } else {
- if (form.isShowList()) {
- // 搜索是否上架的商品
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", form.getGoodsInfoAdded()))
- // 是否列表显示
- .must(QueryBuilders.termQuery("showList", "1"));
- } else {
- // 搜索是否上架的商品
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", form.getGoodsInfoAdded()));
- }
- }
- }
- } else {
- //默认查询是要在列表展示的
- if (form.getKeywords() != null) {
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", "1"));
- } else {
- if (form.isShowList()) {
- // 搜索上架商品
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", "1"))
- // 是否列表显示
- .must(QueryBuilders.termQuery("showList", "1"));
- } else {
- // 搜索上架商品
- boolQuery.must(QueryBuilders.termQuery("goodsInfoAdded", "1"));
- }
- }
- }
-
- //灰度上架:0=否;1=是
- if (!StringUtil.isNotEmptyOrWhiteSpace(form.getAlpha())) {
- //未设置,默认不看灰度上架货品
- boolQuery.must(QueryBuilders.termQuery("alpha", "0"));
- } else {
- if (form.getAlpha().equals("1")) {
- //能看灰度发布商品,不加条件筛选
- } else {
- boolQuery.must(QueryBuilders.termQuery("alpha", "0"));
- }
- }
-
- //Spu展示标记
- if (StringUtil.isNotEmptyOrWhiteSpace(form.getDisplaySpuFlag())) {
- boolQuery.must(QueryBuilders.termQuery("displaySpuFlag", form.getDisplaySpuFlag()));
- }
-
- //查询品牌id
- if (null != form.getBrandId() && form.getBrandId() > 0L) {
- boolQuery.must(termQuery("brand.brandId", form.getBrandId()));
- }
-
- //分类id
- if (null != form.getCatId() && form.getCatId() > 0L) {
- boolQuery.must(termQuery("catId", form.getCatId()));
- }
-
- // 指定商品ID查询
- if (null != form.getGoodsId() && form.getGoodsId() > 0L) {
- boolQuery.must(termQuery("goodsId", form.getGoodsId()));
- }
- // 多个商品ID查询
- if (!ListHelper.isNullOrEmpty(form.getGoodsIds())) {
- boolQuery.must(QueryBuilders.termsQuery("goodsId", form.getGoodsIds()));
- }
- // 指定货品ID查询
- if (null != form.getGoodsInfoId() && form.getGoodsInfoId() > 0L) {
- boolQuery.must(termQuery("goodsInfoId", form.getGoodsInfoId()));
- }
- // 多个货品ID查询
- if (!ListHelper.isNullOrEmpty(form.getGoodsInfoIds())) {
- boolQuery.must(QueryBuilders.termsQuery("goodsInfoId", form.getGoodsInfoIds()));
- }
- // 指定货品编码查询
- if (StringUtils.isNotEmpty(form.getGoodsInfoItemNo())) {
- boolQuery.must(matchQuery("goodsInfoItemNo", form.getGoodsInfoItemNo()));
- }
-
- // 多个货号询
- if (!ListHelper.isNullOrEmpty(form.getGoodsInfoItemNos())) {
- boolQuery.must(QueryBuilders.termsQuery("goodsInfoItemNo", form.getGoodsInfoItemNos()));
- }
-
- // 指定商品编码查询
- if (StringUtils.isNotEmpty(form.getGoodsNo())) {
- boolQuery.must(termQuery("goodsNo", form.getGoodsNo()));
- }
-
- // 多个商品编码
- if (!ListHelper.isNullOrEmpty(form.getGoodsNos())) {
- boolQuery.must(QueryBuilders.termsQuery("goodsNo", form.getGoodsNos()));
- }
-
- // 分类查询
- if (ArrayUtils.isNotEmpty(form.getCids()) && form.isVisitGcpt()) {
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(QueryBuilders.termsQuery("cateList.id", form.getCids()));
- NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("cateList", boolQueryBuilder, ScoreMode.None);
- boolQuery.must(nestedQueryBuilder);
- }
-
- //剔除生产配套分类
- if (ArrayUtils.isNotEmpty(form.getCids()) && !form.isVisitGcpt()) {
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.mustNot(QueryBuilders.termsQuery("cateList.id", form.getCids()));
- NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("cateList", boolQueryBuilder, ScoreMode.None);
- boolQuery.must(nestedQueryBuilder);
- }
-
- // 品牌查询
- if (ArrayUtils.isNotEmpty(form.getBrands())) {
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(QueryBuilders.termsQuery("brand.brandName", form.getBrands()));
- NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("brand", boolQueryBuilder, ScoreMode.None);
- boolQuery.must(nestedQueryBuilder);
- }
-
- // 扩展参数
- if (ArrayUtils.isNotEmpty(form.getParams())) {
- for (String param : form.getParams()) {
- String[] paramArr = param.split(":");
- if ("价格".equals(paramArr[0]) && paramArr.length > 1 && StringUtils.isNotEmpty(paramArr[1])) {
- long[] prices = Arrays.stream(paramArr[1].split("-")).mapToLong(a -> {
- try {
- return Long.parseLong(a);
- } catch (Exception e) {
- log.error("商品根据价格查询出现异常", e);
- return 0L;
- }
- }).toArray();
- RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("goodsInfoPreferPrice");
- rangeQuery.gte(prices[0]);
- rangeQuery.lte(prices.length > 1 ? prices[1] : 0);
- boolQuery.filter(rangeQuery);
- } else {
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(QueryBuilders.termQuery("paramList.attributeName", paramArr[0]));
- boolQueryBuilder.must(QueryBuilders.termQuery("paramList.attributeValue", paramArr[1]));
- NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("paramList", boolQueryBuilder, ScoreMode.None);
- boolQuery.must(nestedQueryBuilder);
- }
- }
- }
-
- // 只显示有货
- if (Objects.nonNull(form.getShowStock()) && "0".equals(form.getShowStock())) {
- // searchRequest.addFilter(FilterBuilders.scriptFilter(filter_script)
- // .addParam(CHECKWARE, Objects.isNull(form.getWareIds()) ? null : form.getWareIds()[0]));
- }
-
-
-
-
- if (form.getGroupGoodsId()){
- CollapseBuilder collapseBuilder = new CollapseBuilder("goodsId");
-
- searchSourceBuilder.collapse(collapseBuilder);
- }
-
-
-
-
-
-
- // 排序
- if (StringUtils.isNotBlank(form.getSort())) {
- switch (form.getSort()) {
- // 价格升序
- case "11D":
- // Script script = new Script(sort_script);
- // ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.ASC);
- // searchSourceBuilder.sort(scriptSortBuilder);
- searchSourceBuilder.sort("goodsInfoMarketPrice",SortOrder.ASC);
- break;
- // 价格降序
- case "1D":
- searchSourceBuilder.sort("goodsInfoMarketPrice",SortOrder.DESC);
- break;
- // 销量降序
- case "2D":
-
- //默认过滤售罄的货品,三大专区,热销
- BoolQueryBuilder includeBoolQuery = QueryBuilders.boolQuery();
-
- //库存大于0
- RangeQueryBuilder goodsInfoStock = rangeQuery("goodsInfoStock")
- .gt(0);
- //允许超卖
- includeBoolQuery.should(QueryBuilders.termQuery("overSold", "1"));
- includeBoolQuery.should(goodsInfoStock);
-
- boolQuery.must(includeBoolQuery);
- searchSourceBuilder.sort("mallSales", SortOrder.DESC);
- searchSourceBuilder.sort("goodsInfoAddedTime",SortOrder.DESC);
- break;
- // 销量升序
- case "22D":
- searchSourceBuilder.sort("mallSales", SortOrder.ASC);
- searchSourceBuilder.sort("goodsInfoAddedTime",SortOrder.ASC);
- break;
- // 创建时间升序
- case "33D":
- searchSourceBuilder.sort("createDate", SortOrder.ASC);
-
-
- break;
- // 创建时间降序
- case "3D":
- searchSourceBuilder.sort("createDate", SortOrder.DESC);
- // searchRequest.addSort(new ScriptSortBuilder(date_sort_script, "number")
- // .order(SortOrder.DESC));
- // searchRequest.addSort(new ScriptSortBuilder(stock_sort_script, "number")
- // .order(SortOrder.DESC));
- break;
- // 收藏升序
- case "44D":
- // searchRequest.addSort("collectionCount", SortOrder.ASC);
- break;
- // 收藏降序
- case "4D":
- // searchRequest.addSort("collectionCount", SortOrder.DESC);
- break;
- // 上架时间升序
- case "55D":
- searchSourceBuilder.sort("goodsInfoAddedTime",SortOrder.ASC);
- break;
- // 上架时间降序
- case "5D":
- searchSourceBuilder.sort("goodsInfoAddedTime",SortOrder.DESC);
- break;
- // 评论数升序
- case "66D":
- // searchRequest.addSort("comment.commentCount", SortOrder.ASC);
- break;
- // 评论数降序
- case "6D":
- // searchRequest.addSort("comment.commentCount", SortOrder.DESC);
- break;
- case "7D":
- String marketJoinGrade = getMarketJoinGrade(form.getPriceGradeId());
- //按照促销活动排序
- if (!StringHelper.isNullOrEmpty(marketJoinGrade)){
- Map<String, Object> params = new HashMap<>();
- params.put("zero",0);
- params.put("one",1);
- params.put("nullCode",null);
- params.put("emptyStr","");
- params.put("marketJoinGrade",marketJoinGrade);
- Script marketJoinGradeScript = new Script(ScriptType.INLINE,"painless",marketing_sort,params);
- ScriptSortBuilder gradeScriptSortBuilder = SortBuilders.scriptSort(marketJoinGradeScript, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
- searchSourceBuilder.sort(gradeScriptSortBuilder);
- }else {
- Map<String, Object> params = new HashMap<>();
- params.put("zero",0);
- params.put("one",1);
- params.put("marketJoinGrade",marketJoinGrade);
- params.put("nullCode",null);
- params.put("emptyStr","");
- Script marketJoinGradeScript = new Script(ScriptType.INLINE,"painless",no_login_marketing_sort,params);
- ScriptSortBuilder gradeScriptSortBuilder = SortBuilders.scriptSort(marketJoinGradeScript, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
- searchSourceBuilder.sort(gradeScriptSortBuilder);
- }
- //按照商品名称带关键字货品
- searchSourceBuilder.sort("weight",SortOrder.DESC);
- //按照库存排序
- Map<String, Object> stockParams = new HashMap<>();
- stockParams.put("zero",0);
- stockParams.put("minusOne",-1);
- stockParams.put("zeroStr","0");
- stockParams.put("oneStr","1");
- Script stockScript = new Script(ScriptType.INLINE, "painless", stock_sort, stockParams);
- ScriptSortBuilder stockOrder = SortBuilders.scriptSort(stockScript, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
- searchSourceBuilder.sort(stockOrder);
-
- // searchSourceBuilder.sort("cat1Sort",SortOrder.ASC);
- // searchSourceBuilder.sort("cat2Sort",SortOrder.ASC);
- // searchSourceBuilder.sort("cat3Sort",SortOrder.ASC);
- searchSourceBuilder.sort("goodsInfoAddedTime",SortOrder.DESC);
- break;
- //根据价格升序
- case "88D":{
- /* if (StringHelper.isNullOrEmpty(form.getPriceGradeId())){
- break;
- }
- String sortField = getPriceLevel(form.getPriceGradeId());
- Script script2 = new Script("def price=_source."+sortField+"; if(price<0){return 0;}else{return price;}");
- ScriptSortBuilder scriptSortBuilder2 = SortBuilders.scriptSort(script2, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.ASC);
- searchSourceBuilder.sort(scriptSortBuilder2);*/
-
- searchSourceBuilder.sort("goodsInfoMarketPrice",SortOrder.ASC);
- }
- break;
- //根据价格降序
- case "8D": {
- /* if (StringHelper.isNullOrEmpty(form.getPriceGradeId())){
- break;
- }
- String sortField = getPriceLevel(form.getPriceGradeId());
- Script script3 = new Script("def price=_source."+sortField+"; if(price<0){return 0;}else{return price;}");
- ScriptSortBuilder scriptSortBuilder3 = SortBuilders.scriptSort(script3, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
- searchSourceBuilder.sort(scriptSortBuilder3);*/
-
- searchSourceBuilder.sort("goodsInfoMarketPrice",SortOrder.DESC);
- }
- break;
- default:
- break;
- }
- }
-
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- if(form.getGoodsInfoAddedTimeSort() != null && form.getGoodsInfoAddedTimeSort() == 0){
- boolQuery.must(termQuery("goodsInfoAdded", "1"));
- searchSourceBuilder.sort(sdf.format(form.getGoodsInfoAddedTime()),SortOrder.DESC);
- }else if(form.getGoodsInfoAddedTimeSort() != null && form.getGoodsInfoAddedTimeSort() == 1){
- boolQuery.must(termQuery("goodsInfoAdded", "1"));
- searchSourceBuilder.sort(sdf.format(form.getGoodsInfoAddedTime()),SortOrder.ASC);
- }
- searchSourceBuilder.query(boolQuery);
-
- AggregationBuilder aggregation =
- AggregationBuilders.nested("paramList","paramList")
- .subAggregation(AggregationBuilders.terms("attributeName")
- .field("paramList.attributeName").size(Integer.MAX_VALUE)
- .subAggregation(AggregationBuilders.terms("attributeValue").field("paramList.attributeValue"))
- );
-
- AggregationBuilder aggregation2 =
- AggregationBuilders.nested("brand","brand")
- .subAggregation(AggregationBuilders.terms("brandName").field("brand.brandName").size(Integer.MAX_VALUE)
- .subAggregation(AggregationBuilders.terms("brandLogo").field("brand.brandLogo"))
- );
- searchSourceBuilder.aggregation(aggregation);
- searchSourceBuilder.aggregation(aggregation2);
- searchSourceBuilder.from((form.getPageNo() - 1) * form.getPageSize()).size(form.getPageSize());
-
- return searchSourceBuilder;
- }
- /**
- * 处理聚合数据,并且过滤掉已选的参数
- *
- * @param resultMap
- * @param aggResult
- * @param brandArr 已选的品牌
- * @param paramArr 已选的扩展参数
- */
- private void processAggResult(Map<String, Object> resultMap, Object aggResult, String[] brandArr, String[] paramArr) {
-
- if (null == aggResult) {
- return;
- }
- // 将聚合结果转化为可操作的json对象
- JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(aggResult));
- // 处理扩展参数
- if (jsonObject.containsKey(PARAMLIST)) {
- List<com.swj.api.zagoods.service.searchplatform.vo.ExpandParamVo> paramVoList = new ArrayList<>();
- Object params = jsonObject.get(PARAMLIST);
- JSONArray paramArray;
- if (params instanceof JSONArray) {
- // 转化为jsonArray
- paramArray = (JSONArray) params;
- } else {
- //只有一个param,构造array
- paramArray = new JSONArray(Arrays.asList((Object) params));
- }
- for (Iterator<?> ite = paramArray.iterator(); ite.hasNext(); ) {
- Object paramObj = ite.next();
- if (paramObj instanceof JSONObject) {
- JSONObject paramJson = (JSONObject) paramObj;
- for (Map.Entry<String, Object> entry : paramJson.entrySet()) {
- // 判断当前的扩展参数是否与已选的相同
- boolean selected = false;
- if (paramArr != null && paramArr.length > 0) {
- for (String paramSelected : paramArr) {
- if (paramSelected.split(":")[0].equals(entry.getKey())) {
- selected = true;
- break;
- }
- }
- }
- // 未选中,则放入聚合结果
- if (!selected) {
- com.swj.api.zagoods.service.searchplatform.vo.ExpandParamVo paramVo = new com.swj.api.zagoods.service.searchplatform.vo.ExpandParamVo(entry.getKey());
- if (entry.getValue() instanceof List) {
- List<String> paramValues = (List<String>) entry.getValue();
- for (String paramValue : paramValues) {
- paramVo.addParamValue(new com.swj.api.zagoods.service.searchplatform.vo.ParamValueVo(paramValue));
- }
- } else {
- paramVo.addParamValue(new com.swj.api.zagoods.service.searchplatform.vo.ParamValueVo(entry.getValue().toString()));
- }
- //根据double值对扩展参数值数组进行排序
- sortParamValWithDoubleVal(paramVo);
- paramVoList.add(paramVo);
- }
- }
- }
- }
- resultMap.put("params", paramVoList);
- }
- // 处理品牌
- if (jsonObject.containsKey(BRAND)) {
- List<com.swj.api.zagoods.service.searchplatform.vo.BrandVo> brandVoList = new ArrayList<>();
- // 获取品牌信息
- Object brandObj = jsonObject.get(BRAND);
- // 已选择的品牌转换为列表
- List<String> brandList;
- if (brandArr == null || brandArr.length == 0) {
- brandList = new ArrayList<>();
- } else {
- brandList = Arrays.asList(brandArr);
- }
-
- if (brandObj instanceof JSONArray) {
- JSONArray brands = (JSONArray) brandObj;
- for (Object branObj : brands.toArray()) {
- JSONObject jsonObj = (JSONObject) branObj;
- for (Map.Entry<String, Object> entry : jsonObj.entrySet()) {
- if (entry.getKey() != null && !brandList.contains(String.valueOf(entry.getKey()))) {
- brandVoList.add(new com.swj.api.zagoods.service.searchplatform.vo.BrandVo(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
- }
- }
- }
- } else if (brandObj instanceof JSONObject) {
- JSONObject brand = (JSONObject) brandObj;
- for (Map.Entry<String, Object> entry : brand.entrySet()) {
- if (entry.getKey() != null && !brandList.contains(String.valueOf(entry.getKey()))) {
- brandVoList.add(new com.swj.api.zagoods.service.searchplatform.vo.BrandVo(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
- }
- }
- } else {
- if (!brandList.contains(brandObj.toString())) {
- brandVoList.add(new com.swj.api.zagoods.service.searchplatform.vo.BrandVo(brandObj.toString()));
- }
- }
-
- resultMap.put("brands", brandVoList);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。