package com.ssj.es.service;

import com.ssj.es.entiy.ElasticEntity;
import com.ssj.es.service.base.BaseElasticService;
import com.ssj.es.utils.ElasticUtil;
import com.ssj.framework.core.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

//kmt_exercise_questions 练习册相关的引擎操作类
//es查询中不支持  as 返回别名的方式，如要使用别名请自行代码中更改。

@SuppressWarnings("rawtypes")
@Component
public class ExerciseQuestionSearchService extends BaseElasticService{

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private static String indexName="kmt_exercise_questions";

	//刷新全部ES的数据
	public void refreshAll() {
		
		
	}
	
	//按id删除
	public void delete(String id) {
		ElasticEntity entity=new ElasticEntity();
		entity.setId(id);
		this.deleteOne(indexName, entity);
	}
	
	//保存、更新，如果id为空，不做保存。
	public void save(Map map) {
		ElasticEntity entity=new ElasticEntity();
		if(!map.containsKey("id")) {
			return;
		}
		entity.setId(map.get("id").toString());
		entity.setData(map);
		this.insertOrUpdateOne(indexName, entity, true);
	}

	//保存、更新，如果id为空，不做保存。
	public void saveImmediate(Map map) {
		ElasticEntity entity=new ElasticEntity();
		if(!map.containsKey("id")) {
			return;
		}
		entity.setId(map.get("id").toString());
		entity.setData(map);
		this.insertOrUpdateOneImmediate(indexName, entity, true);
	}
	
	public List<Map> findQuestionByQuestionIds(List<String> questionIds){
		 List<Map> data=new ArrayList<Map>();
		 try {
			 IdsQueryBuilder idsQueryBuilder=QueryBuilders.idsQuery();
			 for (String id : questionIds) {
				 idsQueryBuilder.addIds(id);
			 }
	         QueryBuilder queryBuilder = QueryBuilders.boolQuery()
	                    .mustNot(QueryBuilders.termsQuery("dealStatus","0","1","2","3","6","7"))
	                    .must(idsQueryBuilder)
	                    .must(QueryBuilders.existsQuery("answerJson"))
	                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", "[]"))
	                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", ""));
	         
	                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
	                searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
	                searchSourceBuilder.sort(SortBuilders.fieldSort("createTime").order(SortOrder.ASC));
	                data = this.search(indexName,searchSourceBuilder,Map.class);
	        } catch (Exception e) {
	        	e.printStackTrace();
	        }
		 return data;
	}
	
	
	
	public int countByBookIdAndPageIndex (String bookId, int pageIndex) {
		 try {
			
	         QueryBuilder queryBuilder = QueryBuilders.boolQuery()
	                    .must(QueryBuilders.termQuery("bookId.keyword", bookId))
	                    .must(QueryBuilders.termQuery("pageIndex", pageIndex));
	         
	                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
	                return this.count(indexName,searchSourceBuilder).intValue();
	        } catch (Exception e) {
	        	e.printStackTrace();
	        }
		 return 0;
	}
	
	
	public List<Map> findQuestionByBookIdAndPage(String bookId, String unitId, String bookCourseId,List<Integer> pageIndex, int bookYear){
		List<Map> data=new ArrayList<Map>();
		
		QueryBuilder shouldQueryBuilder = QueryBuilders.boolQuery()
	            .should(QueryBuilders.termQuery("isCommonFlag", "0"))
	            .should(QueryBuilders.termQuery("questionYear", bookYear));
		
		 try {
				 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
						 	.mustNot(QueryBuilders.termsQuery("dealStatus","0","1","2","3","6","7"))
		                    .must(QueryBuilders.termQuery("bookId.keyword", bookId))
		                    
		                    .must(QueryBuilders.termsQuery("pageIndex",pageIndex))
		                    
		                    .must(shouldQueryBuilder)
		                    .must(QueryBuilders.existsQuery("answerJson"))
		                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", "[]"))
		                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", ""));
		         
		         if(StringUtils.isNotEmpty(unitId)) {
		        	 queryBuilder.must(QueryBuilders.termQuery("unitId.keyword", unitId));
		         }
		         if(StringUtils.isNotEmpty(unitId)) {
		        	 queryBuilder.must(QueryBuilders.termQuery("bookCourseId.keyword", bookCourseId));
		         }
            
                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
                searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));

                data = this.search(indexName,searchSourceBuilder,Map.class);
	        } catch (Exception e) {
	        	e.printStackTrace();
	        }
		 
		 return data;
    }
	
	

	public List<Map> findAnswerByExerciseBookCourseId(String exerciseBookCourseId, int bookYear) {
		List<Map> data=new ArrayList<Map>();

		QueryBuilder shouldQueryBuilder = QueryBuilders.boolQuery()
	            .should(QueryBuilders.termQuery("isCommonFlag", "0"))
	            .should(QueryBuilders.termQuery("questionYear", bookYear));

		 try {
		           QueryBuilder queryBuilder = QueryBuilders.boolQuery()
		        		 	.mustNot(QueryBuilders.termsQuery("dealStatus","0","1","2","3","6","7"))
		                    .must(QueryBuilders.termQuery("bookCourseId.keyword", exerciseBookCourseId))
		                    .must(shouldQueryBuilder)
		                    .must(QueryBuilders.existsQuery("answerJson"))
		                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", "[]"))
		                    .mustNot(QueryBuilders.termQuery("answerJson.keyword", ""));
		         
	                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
	                searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));

	                data = this.search(indexName,searchSourceBuilder,Map.class);
	        } catch (Exception e) {
	        	e.printStackTrace();
	        }
		 
		 return data;
	}


	/**
	 * 查询老师下的所有kmt题目
	 * @param param
	 * @return
	 */
	public Map<String, Object> findAllKmtQuestions (Map<String, Object> param){
		int pageNo = Integer.parseInt(param.get("pageNo") + "");
		int pageSize = Integer.parseInt(param.get("pageSize") + "");
		int dealType = Integer.parseInt(param.get("dealType") + "");
		List<String> findUserIds = (List)param.get("findUserIds");
		List<Map> data = new ArrayList<>();
		BoolQueryBuilder filterQuery = null;
		if (dealType == 1){
			filterQuery = QueryBuilders.boolQuery()
					.must(QueryBuilders.queryStringQuery(param.getOrDefault("userId", "").toString()).field("handleUserId.keyword"))
					.must(QueryBuilders.termsQuery("dealStatus", "0", "1"));
		} else  if (dealType == 2){
			filterQuery = QueryBuilders.boolQuery()
					.must(QueryBuilders.queryStringQuery(param.getOrDefault("userId", "").toString()).field("auditingUserId.keyword"))
					.must(QueryBuilders.termsQuery("dealStatus", "3", "7"));
			if (CollectionUtils.isNotEmpty(findUserIds)){
				filterQuery.must(QueryBuilders.termsQuery("handleUserId.keyword", findUserIds));
			}
		} else {
			filterQuery = QueryBuilders.boolQuery()
					.mustNot(QueryBuilders.termQuery("dealStatus", 6));
			if (CollectionUtils.isNotEmpty(findUserIds)){
				filterQuery.must(QueryBuilders.boolQuery().should(
								QueryBuilders.termsQuery("auditingUserId.keyword", findUserIds))
						.should(QueryBuilders.termsQuery("handleUserId.keyword", findUserIds)));
			}
		}

		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.mustNot(QueryBuilders.existsQuery("bookId"))
				.must(QueryBuilders.termsQuery("questionClassType", "0", "2"))
				.must(filterQuery);

		//年份
		int beginYear = Integer.parseInt(param.getOrDefault("beginYear" , "0").toString());
		int endYear =  Integer.parseInt(param.getOrDefault("endYear" , "0").toString());
		if (beginYear > 0 && endYear > 0){
			queryBuilder.must(QueryBuilders.queryStringQuery(beginYear + "").field("beginYear"))
					.must(QueryBuilders.queryStringQuery(endYear + "").field("endYear"));
		}

		//地区
		String province = (String)param.getOrDefault("questionProvince", "");
		String city =  (String)param.getOrDefault("questionCity", "");
		String country =  (String)param.getOrDefault("questionCountry", "");
		if (StringUtils.isNotBlank(province)){
			queryBuilder.must(QueryBuilders.queryStringQuery(province).field("questionProvince.keyword"));
			if (StringUtils.isNotBlank(city)){
				queryBuilder.must(QueryBuilders.queryStringQuery(city).field("questionCity.keyword"));
				if (StringUtils.isNotBlank(country)){
					queryBuilder.must(QueryBuilders.queryStringQuery(country).field("questionCountry.keyword"));
				}
			}
		}

		Map<String, Object> result = new HashMap<>();
		result.put("data", null);
		result.put("total", 0L);
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				if (dealType != 3){
					searchSourceBuilder.sort(SortBuilders.fieldSort("dealStatus").order(SortOrder.DESC));
					searchSourceBuilder.sort(SortBuilders.fieldSort("repulseTime").order(SortOrder.ASC));
				}
				searchSourceBuilder.sort(SortBuilders.fieldSort("handlerSubmitTime.keyword").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("parentId.keyword").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("id.keyword").order(SortOrder.ASC));

				searchSourceBuilder.from((pageNo - 1) * pageSize);
				searchSourceBuilder.size(pageSize);
				logger.info(searchSourceBuilder.toString());
				result = this.searchDataAndCount(indexName,searchSourceBuilder,Map.class);
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return result;
	}

	/**
	 * 根据年级版本上下册等信息查询kmt题目列表
	 * @param requestData
	 * @param userId
	 * @param userIdList
	 * @return
	 */
	public Map<String, Object> findKmtQuestionByGradeSubjectVersionSemester (Map<String, String> requestData, String userId,  List<String> userIdList){
		Map<String, Object> result = new HashMap<>();
		result.put("data", null);
		result.put("total", 0L);
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.mustNot(QueryBuilders.existsQuery("book_id"))
				.must(QueryBuilders.termsQuery("question_class_type", "0", "2"))
				.must(this.getKmtQuestionSearchFilterQuery(Integer.parseInt(requestData.get("dealType")), userId, userIdList));

		//年份
		if (((Integer.parseInt(requestData.get("beginYear")) > 0 && Integer.parseInt(requestData.get("endYear")) > 0))){
			queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("beginYear")).field("begin_year"))
					.must(QueryBuilders.queryStringQuery(requestData.get("endYear")).field("end_year"));
		}

		//地区
		if (StringUtils.isNotBlank(requestData.get("questionProvince"))){
			queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionProvince")).field("question_province.keyword"));
			if (StringUtils.isNotBlank(requestData.get("questionCity"))){
				queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionCity")).field("question_city.keyword"));
				if (StringUtils.isNotBlank(requestData.get("questionCountry"))){
					queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionCountry")).field("question_country.keyword"));
				}
			}
		}

		//科目
		if (StringUtils.isNotEmpty(requestData.get("courseName"))){
			queryBuilder.must(QueryBuilders.termQuery("course_name.keyword", requestData.get("courseName")));
		}
		//年级
		if (StringUtils.isNotEmpty(requestData.get("grade"))){
			queryBuilder.must(QueryBuilders.termQuery("grade.keyword", requestData.get("grade")));
		}
		//版本
		if (0 < Integer.parseInt(requestData.get("versionType"))){
			queryBuilder.must(QueryBuilders.termQuery("version", requestData.get("versionType")));
		}
		//上下册
		if (0 < Integer.parseInt(requestData.get("semester"))){
			queryBuilder.must(QueryBuilders.termQuery("semester", requestData.get("semester")));
		}
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.collapse(new CollapseBuilder("question_id.keyword"));
				if (Integer.parseInt(requestData.get("dealType")) != 3){
					searchSourceBuilder.sort(SortBuilders.fieldSort("deal_status").order(SortOrder.DESC));
					searchSourceBuilder.sort(SortBuilders.fieldSort("repulse_time").order(SortOrder.ASC));
				}
				searchSourceBuilder.sort(SortBuilders.fieldSort("handler_submit_time").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("parent_id.keyword").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("id.keyword").order(SortOrder.ASC));

				searchSourceBuilder.from((Integer.parseInt(requestData.get("pageNo")) - 1) * Integer.parseInt(requestData.get("pageSize")));
				searchSourceBuilder.size(Integer.parseInt(requestData.get("pageSize")));
				searchSourceBuilder.aggregation(AggregationBuilders.cardinality("question_count").field("question_id.keyword"));
				logger.info(searchSourceBuilder.toString());
				result = this.searchDataAndCount("kmt_exercise_question_know", searchSourceBuilder, Map.class, "question_count");
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return result;
	}

	/**
	 * kmt题目查询的一个过滤条件
	 * @param dealType
	 * @param userId
	 * @param findUserIds
	 * @return
	 */
	private QueryBuilder getKmtQuestionSearchFilterQuery (int dealType, String userId, List<String> findUserIds){
		BoolQueryBuilder filterQuery;
		if (dealType == 1){
			filterQuery = QueryBuilders.boolQuery()
					.must(QueryBuilders.queryStringQuery(userId).field("handle_user_id.keyword"))
					.must(QueryBuilders.termsQuery("deal_status", "0", "1"));
		} else  if (dealType == 2){
			filterQuery = QueryBuilders.boolQuery()
					.must(QueryBuilders.queryStringQuery(userId).field("auditing_user_id.keyword"))
					.must(QueryBuilders.termsQuery("deal_status", "3", "7"));
			if (CollectionUtils.isNotEmpty(findUserIds)){
				filterQuery.must(QueryBuilders.termsQuery("handle_user_id.keyword", findUserIds));
			}
		} else {
			filterQuery = QueryBuilders.boolQuery()
					.mustNot(QueryBuilders.termQuery("deal_status.keyword", 6));
			if (CollectionUtils.isNotEmpty(findUserIds)){
				filterQuery.must(QueryBuilders.boolQuery().should(
								QueryBuilders.termsQuery("auditing_user_id.keyword", findUserIds))
								.should(QueryBuilders.termsQuery("handle_user_id.keyword", findUserIds)));
			}
		}
		return filterQuery;
	}

	/**
	 * 知识点查询kmt题目
	 * @param requestData
	 * @param userId
	 * @param userIdList
	 * @return
	 */
	public Map<String, Object> findKmtQuestionByDetailId (Map<String, String> requestData, String userId,  List<String> userIdList){
		Map<String, Object> result = new HashMap<>();
		result.put("data", null);
		result.put("total", 0L);
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.mustNot(QueryBuilders.existsQuery("book_id"))
				.must(QueryBuilders.termsQuery("question_class_type", "0", "2"))
				.must(this.getKmtQuestionSearchFilterQuery(Integer.parseInt(requestData.get("dealType")), userId, userIdList));

		//年份
		if (((Integer.parseInt(requestData.get("beginYear")) > 0 && Integer.parseInt(requestData.get("endYear")) > 0))){
			queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("beginYear")).field("begin_year"))
					.must(QueryBuilders.queryStringQuery(requestData.get("endYear")).field("end_year"));
		}

		//地区
		if (StringUtils.isNotBlank(requestData.get("questionProvince"))){
			queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionProvince")).field("question_province.keyword"));
			if (StringUtils.isNotBlank(requestData.get("questionCity"))){
				queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionCity")).field("question_city.keyword"));
				if (StringUtils.isNotBlank(requestData.get("questionCountry"))){
					queryBuilder.must(QueryBuilders.queryStringQuery(requestData.get("questionCountry")).field("question_country.keyword"));
				}
			}
		}


		//知识点
		if (StringUtils.isNotEmpty(requestData.get("detailId"))){
			queryBuilder.must(QueryBuilders.termQuery("how_detail_sort_id.keyword", requestData.get("detailId")));
		}
		//考点
		if (StringUtils.isNotEmpty(requestData.get("pointId"))){
			queryBuilder.must(QueryBuilders.termQuery("how_detail_kd_sort_id.keyword", requestData.get("pointId")));
		}
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.collapse(new CollapseBuilder("question_id.keyword"));
				if (Integer.parseInt(requestData.get("dealType")) != 3) {
					searchSourceBuilder.sort(SortBuilders.fieldSort("deal_status").order(SortOrder.DESC));
					searchSourceBuilder.sort(SortBuilders.fieldSort("repulse_time").order(SortOrder.ASC));
				}
				searchSourceBuilder.sort(SortBuilders.fieldSort("parent_id.keyword").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("handler_submit_time").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("parent_id.keyword").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("id.keyword").order(SortOrder.ASC));

				searchSourceBuilder.from((Integer.parseInt(requestData.get("pageNo")) - 1) * Integer.parseInt(requestData.get("pageSize")));
				searchSourceBuilder.size(Integer.parseInt(requestData.get("pageSize")));
				searchSourceBuilder.aggregation(AggregationBuilders.cardinality("question_count").field("question_id.keyword"));
				logger.info(searchSourceBuilder.toString());
				result = this.searchDataAndCount("kmt_exercise_question_know", searchSourceBuilder, Map.class, "question_count");
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return result;
	}

	public <T> List<T> getById(String id, Class<T> c){

		 try {
			 IdsQueryBuilder idsQueryBuilder=QueryBuilders.idsQuery();
			 idsQueryBuilder.addIds(id);
	         QueryBuilder queryBuilder = QueryBuilders.boolQuery()
	                    .must(idsQueryBuilder);
	                    SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				        return   this.search(indexName,searchSourceBuilder,c);

	        } catch (Exception e) {
	        	e.printStackTrace();
	        }
		 return null;
	}

	/**
	 * 查询打回的题目
	 * @param requestData
	 * @return
	 */
	public List<Map> findKmtRollbackQuestions (Map<String, String> requestData){
		List<Map> data = new ArrayList<>();
		String bookId = Optional.ofNullable(requestData.get("bookId")).orElse("");
		BoolQueryBuilder queryBuilder;
		if (StringUtils.isBlank(bookId)) {
			queryBuilder = QueryBuilders.boolQuery()
					.mustNot(QueryBuilders.existsQuery("bookId"))
					.filter(QueryBuilders.termQuery("conciseBakId.keyword", requestData.get("detailId")))
					.filter(
							QueryBuilders.boolQuery()
									.should(
											QueryBuilders.boolQuery()
													.filter(QueryBuilders.termQuery("handleUserId.keyword", requestData.get("teacherId")))
													.filter(QueryBuilders.termQuery("dealStatus", 1))
									)
									.should(QueryBuilders.boolQuery()
											.filter(QueryBuilders.termQuery("auditingUserId.keyword", requestData.get("teacherId")))
											.filter(QueryBuilders.termQuery("dealStatus", 7))
									)
					);
		} else {
			queryBuilder = QueryBuilders.boolQuery()
					.filter(QueryBuilders.queryStringQuery(bookId).field("bookId.keyword"))
					.filter(QueryBuilders.boolQuery()
							.should(QueryBuilders.boolQuery()
									.filter(QueryBuilders.queryStringQuery(requestData.get("teacherId")).field("handleUserId.keyword"))
									.filter(QueryBuilders.termQuery("dealStatus", 1)))
							.should(QueryBuilders.boolQuery()
									.filter(QueryBuilders.queryStringQuery(requestData.get("teacherId")).field("auditingUserId.keyword"))
									.filter(QueryBuilders.termQuery("dealStatus", 7)))
							.should(QueryBuilders.boolQuery()
									.filter(QueryBuilders.queryStringQuery(requestData.get("teacherId")).field("analysisUserId.keyword"))
									.filter(QueryBuilders.termQuery("dealStatus", 8)))
							.should(QueryBuilders.boolQuery()
									.filter(QueryBuilders.queryStringQuery(requestData.get("teacherId")).field("analysisAuditerId.keyword"))
									.filter(QueryBuilders.termQuery("dealStatus", 10))));
		}
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				if (StringUtils.isBlank(bookId)) {
					searchSourceBuilder.sort(SortBuilders.fieldSort("handlerSubmitTime.keyword").order(SortOrder.ASC));
					searchSourceBuilder.sort(SortBuilders.fieldSort("parentId.keyword").order(SortOrder.ASC));
				}
				searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
				searchSourceBuilder.sort(SortBuilders.fieldSort("id.keyword").order(SortOrder.ASC));
				System.out.println(searchSourceBuilder.toString());
				data = this.search("kmt_exercise_questions", searchSourceBuilder, Map.class);
			}
		} catch (Exception e){
			logger.error("查询打回题目异常", e);
		}
		return data;
	}


	/**
	 * 查询小题下的加工审核人
	 * @param parentId
	 * @return
	 */
	public List<Map> findHandleUserIdAndAuditingUserId (String parentId) {
		List<Map> data = null;
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.must(QueryBuilders.termQuery("parentId.keyword", parentId))
				.must(QueryBuilders.existsQuery("handleUserId.keyword"))
				.must(QueryBuilders.existsQuery("auditingUserId.keyword"));
		try{
			if ( null != queryBuilder){

				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				String[] include = {"handleUserId", "auditingUserId"};
				String[] exclude = {};
				searchSourceBuilder.fetchSource(include, exclude);
				searchSourceBuilder.from(0);
				searchSourceBuilder.size(1);
				log.info(searchSourceBuilder.toString());
				data = this.search("kmt_exercise_questions", searchSourceBuilder, Map.class);
			}
		} catch (Exception e){
			log.error("查询打回题目异常", e);
		}
		return data;
	}

	/**
	 * 查询大小题
	 * @param parentId
	 * @return
	 */
	public List<Map> findKmtQuestionsByParentId (String parentId){
		List<Map> result = null;



		QueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.mustNot(QueryBuilders.termQuery("dealStatus", 6))
				.must(QueryBuilders.termQuery("parentId.keyword", parentId));
		queryBuilder = QueryBuilders.boolQuery().should(QueryBuilders.termQuery("id.keyword", parentId))
				.should(queryBuilder);
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.size(1500);
				searchSourceBuilder.sort(SortBuilders.fieldSort("num").order(SortOrder.ASC));
				logger.info(searchSourceBuilder.toString());
				result = this.search(indexName,searchSourceBuilder, Map.class);
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return result;
	}

	/**
	 * 查询答案校对的练习册id
	 * @param userId 用户id
	 * @param type 类型， 6未校对，7已校对
	 * @return
	 */
	public List<String> findAnswerCorrectExerciseBookId (String userId, int type){
		List<String> exerciseBookIds = new LinkedList<>();
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
				.must(QueryBuilders.termQuery("answerCorrecterId.keyword", userId))
				.must(QueryBuilders.existsQuery("bookId.keyword"))
				.must(QueryBuilders.rangeQuery("dealStatus").gte(4))
				.mustNot(QueryBuilders.termsQuery("dealStatus", "6", "7"));
		if (type == 6){
			queryBuilder.must(QueryBuilders.termQuery("proofreadStatus", 0));
		} else {
			queryBuilder.mustNot(QueryBuilders.termQuery("proofreadStatus", 0));
		}
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.size(0);
				searchSourceBuilder.aggregation(AggregationBuilders.terms("exercise_book_id").field("exerciseBookId.keyword").size(2000));
				logger.info(searchSourceBuilder.toString());
				SearchResponse searchResponse = this.searchResponse(indexName, searchSourceBuilder);
				Terms terms = searchResponse.getAggregations().get("exercise_book_id"); //考点列表
				for (int i = 0; i < terms.getBuckets().size(); i++) {
					if (StringUtil.isNotBlank(terms.getBuckets().get(i).getKeyAsString())) {
						exerciseBookIds.add(terms.getBuckets().get(i).getKeyAsString());
					}
				}
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return exerciseBookIds;
	}

	public boolean insertOrUpdateBatch(List<ElasticEntity> elasticEntityList) {
		BulkRequest bulkRequest = new BulkRequest();
		UpdateRequest updateRequest;
		for (ElasticEntity elasticEntity : elasticEntityList) {
			updateRequest = new UpdateRequest(indexName, elasticEntity.getId())
					.doc(elasticEntity.getData())
					.upsert(elasticEntity.getData());
			bulkRequest.add(updateRequest);
		}

		return this.bulk(bulkRequest);
	}

	/**
	 * 通过id列表批量查询题目
	 * @param questionIds
	 * @return
	 */
	public List<Map> findAllExerciseQuestionsByQuestionIds (List<String> questionIds){
		List<Map> result = null;
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("id.keyword", questionIds.toArray()));
		try{
			if ( null != queryBuilder){
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.size(1000);
				result = this.search(indexName, searchSourceBuilder, Map.class);
			}
		} catch (Exception e){
			logger.error("查询es异常", e);
		}
		return result;
	}

	/**
	 * 查询大小题的题目
	 *
	 * @param parentQuestionIdList 大题id
	 *
	 * @return 题目
	 */
	public List<Map> findFullBigQuestionByParentId(List<String> parentQuestionIdList) {
		List<Map> result = null;
		parentQuestionIdList = parentQuestionIdList.stream()
				.filter(StringUtils::isNotBlank)
				.distinct()
				.collect(Collectors.toList());
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().should(QueryBuilders.termsQuery("id.keyword", parentQuestionIdList))
				.should(QueryBuilders.termsQuery("parentId.keyword", parentQuestionIdList));
		try {
			if (null != queryBuilder) {
				SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
				searchSourceBuilder.size(1000);
				result = this.search(indexName, searchSourceBuilder, Map.class);
			}
		} catch (Exception e) {
			logger.error("查询es异常", e);
		}
		return result;
	}
}
