- 浏览: 46779 次
最新评论
要从现在的公司离职了。记录一下自己针对我们的自己需求所做的搜索。
基于Spring data,ES 2.X版本的
基于Spring data,ES 2.X版本的
package com.xxxx.cms.elasticsearch.domain; import java.util.Calendar; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldIndex; import org.springframework.data.elasticsearch.annotations.FieldType; import com.xxxx.cms.content.common.domain.CmsContent; @Document(indexName = "cms", type = "contentIndex") public class ContentIndex { /** 主键ID */ @Id private Long id; /** 标题 */ @Field(store = true, type = FieldType.String, analyzer = "ik") private String title; /** 标签 */ @Field(store = true, type = FieldType.String, analyzer = "ik") private String[] tags; /** 相关股票 */ @Field(store = true, type = FieldType.String, analyzer = "ik") private String[] relatedStocks; /** 摘要 */ @Field(store = true, type = FieldType.String, analyzer = "ik") private String description; /** 内容 */ @Field(store = false, type = FieldType.String, analyzer = "ik") private String contentTxt; // 状态值 @Field(store = true, type = FieldType.Integer, index = FieldIndex.not_analyzed) private Integer status; @Field(store = true, type = FieldType.Integer, index = FieldIndex.not_analyzed) private Long channelId; // 栏目ID @Field(store = true, type = FieldType.Integer, index = FieldIndex.not_analyzed) private Integer typeId; @Field(store = true, type = FieldType.Long, index = FieldIndex.not_analyzed) private Long flagBit; @Field(store = true, type = FieldType.Integer, index = FieldIndex.not_analyzed) private Long topicId; /** 创建时间 */ @Field(store = true, type = FieldType.Date, index = FieldIndex.not_analyzed) private Calendar createdDate; /** 发布时间 */ @Field(store = true, type = FieldType.Date, index = FieldIndex.not_analyzed) private Calendar releasedDate; public ContentIndex() { } public ContentIndex(Long id, Integer status, String title, String[] tags, String[] relatedStocks, String description, String contentTxt, Long channelId, Integer typeId, Long flagBit, Long topicId, Calendar createdDate, Calendar releasedDate) { this.id = id; this.status = status; this.title = title; this.tags = tags; this.relatedStocks = relatedStocks; this.channelId = channelId; this.typeId = typeId; this.flagBit = flagBit; this.topicId = topicId; this.createdDate = createdDate; this.releasedDate = releasedDate; this.contentTxt = contentTxt; if (StringUtils.isBlank(description) && StringUtils.isNotEmpty(contentTxt)) { String contTxt = Jsoup.parse(contentTxt).text(); this.description = contTxt.length() > 200 ? contTxt.substring(0, 200) : contTxt; } else { this.description = description; } } public ContentIndex(CmsContent cmsContent) { this.id = cmsContent.getId(); this.status = cmsContent.getStatus().getIndex(); this.title = cmsContent.getTitle(); this.tags = cmsContent.getESTags(); this.relatedStocks = cmsContent.getESRelatedStocks(); this.channelId = cmsContent.getChannelId(); this.typeId = cmsContent.getTypeId(); this.flagBit = cmsContent.getFlagBit(); this.topicId = cmsContent.getTopicId(); this.createdDate = cmsContent.getCreatedDate(); this.releasedDate = cmsContent.getReleasedDate(); this.contentTxt = cmsContent.getContentTxt(); if (StringUtils.isBlank(cmsContent.getDescription()) && StringUtils.isNotEmpty(contentTxt)) { String contTxt = Jsoup.parse(contentTxt).text(); this.description = contTxt.length() > 200 ? contTxt.substring(0, 200) : contTxt; } else { this.description = cmsContent.getDescription(); } } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String[] getTags() { return tags; } public void setTags(String[] tags) { this.tags = tags; } public String[] getRelatedStocks() { return relatedStocks; } public void setRelatedStocks(String[] relatedStocks) { this.relatedStocks = relatedStocks; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getContentTxt() { return contentTxt; } public void setContentTxt(String contentTxt) { this.contentTxt = contentTxt; } public Long getChannelId() { return channelId; } public void setChannelId(Long channelId) { this.channelId = channelId; } public Integer getTypeId() { return typeId; } public void setTypeId(Integer typeId) { this.typeId = typeId; } public Long getFlagBit() { return flagBit; } public void setFlagBit(Long flagBit) { this.flagBit = flagBit; } public Long getTopicId() { return topicId; } public void setTopicId(Long topicId) { this.topicId = topicId; } public Calendar getCreatedDate() { return createdDate; } public void setCreatedDate(Calendar createdDate) { this.createdDate = createdDate; } public Calendar getReleasedDate() { return releasedDate; } public void setReleasedDate(Calendar releasedDate) { this.releasedDate = releasedDate; } }
package com.xxxx.cms.elasticsearch.service.impl; import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.task.TaskExecutor; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.stereotype.Service; import com.aicai.appmodel.domain.result.ModelResult; import com.aicai.appmodel.page.DataPage; import com.xxxx.cms.channel.common.domain.CmsChannelDefine; import com.xxxx.cms.channel.common.service.CmsChannelDefineService; import com.xxxx.cms.channel.common.type.ChannelDefineType; import com.xxxx.cms.config.props.EsProps; import com.xxxx.cms.content.common.domain.CmsContent; import com.xxxx.cms.content.common.domain.CmsContentStock; import com.xxxx.cms.content.common.domain.CmsContentTag; import com.xxxx.cms.content.common.domain.CmsContentTxt; import com.xxxx.cms.content.common.type.ContentStatus; import com.xxxx.cms.content.common.vo.CmsContentQueryVo; import com.xxxx.cms.content.manager.CmsContentManager; import com.xxxx.cms.content.manager.CmsContentStockManager; import com.xxxx.cms.content.manager.CmsContentTagManager; import com.xxxx.cms.content.manager.CmsContentTxtManager; import com.xxxx.cms.elasticsearch.common.domain.ContentSearchResult; import com.xxxx.cms.elasticsearch.common.service.ContentIndexReadService; import com.xxxx.cms.elasticsearch.constant.ElasticSearchConstant; import com.xxxx.cms.elasticsearch.domain.ContentIndex; import com.xxxx.cms.elasticsearch.domain.HelpCenterContentIndex; import com.xxxx.cms.elasticsearch.manager.ContentIndexManager; import com.xxxx.cms.elasticsearch.repositories.ContentIndexRepository; import com.xxxx.cms.elasticsearch.repositories.HelpCenterRepository; @Service("contentIndexReadService") public class ContentIndexReadServiceImpl implements ContentIndexReadService, InitializingBean { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private ContentIndexManager contentIndexManager; @Autowired private ContentIndexRepository contentIndexRepository; @Autowired private HelpCenterRepository helpCenterRepository; @Autowired private ElasticsearchOperations elasticsearchTemplate; @Autowired private CmsContentStockManager cmsContentStockManager; @Autowired private CmsContentTagManager cmsContentTagManager; @Autowired private CmsContentManager cmsContentManager; @Autowired private CmsContentTxtManager cmsContentTxtManager; @Autowired private CmsChannelDefineService cmsChannelDefineService; @Autowired private TaskExecutor taskExecutor; @Autowired private EsProps esProps; private final int page_size = 1000; @SuppressWarnings("unchecked") @Override public void afterPropertiesSet() throws Exception { if (esProps.isInit() == false) return; boolean delContentIdxFlag = elasticsearchTemplate.deleteIndex(ElasticSearchConstant.CMS_INDEX); logger.warn("ES删除ContentIndex索引:{}", delContentIdxFlag); if (delContentIdxFlag == false) { logger.error("ES删除ContentIndex索引失败,重建索引退出"); return; } boolean createContentIdxFlag = elasticsearchTemplate.createIndex(ElasticSearchConstant.CMS_INDEX); logger.warn("ES创建cms索引:{}", createContentIdxFlag); if (createContentIdxFlag == false) { logger.error("ES删除ContentIndex索引失败,重建索引退出"); return; } boolean contentIndexMappingFlag = elasticsearchTemplate.putMapping(ContentIndex.class); logger.warn("ES创建cms:contentIndex映射:{}", contentIndexMappingFlag); elasticsearchTemplate.getMapping(ElasticSearchConstant.CMS_INDEX, ElasticSearchConstant.CMS_CONTENT_TYPE).entrySet() .forEach(obj -> logger.warn("ES创建ContentIndex索引,映射关系为:{}", obj)); boolean helpCenterIndexMappingFlag = elasticsearchTemplate.putMapping(HelpCenterContentIndex.class); logger.warn("ES创建cms:helpCenterIndex映射:{}", helpCenterIndexMappingFlag); elasticsearchTemplate.getMapping(ElasticSearchConstant.CMS_INDEX, ElasticSearchConstant.CMS_HELP_CENTER_TYPE).entrySet() .forEach(obj -> logger.warn("ES创建helpCenterIndex索引,映射关系为:{}", obj)); indexInit(); helpCenterInit(); } private void indexInit() { taskExecutor.execute(() -> { logger.info("初始化contentIndex开始"); LocalDateTime beginTime = LocalDateTime.now(); contentIndexRepository.deleteAll(); DataPage<CmsContent> dataPage = new DataPage<>(); dataPage.setPageSize(page_size); dataPage.setOrder("ASC"); dataPage.setOrderBy("released_date"); Calendar beginReleasedDate = Calendar.getInstance(); // 只初始化一年内的资讯 beginReleasedDate.setTimeInMillis(LocalDateTime.now().minusYears(1).toInstant(ZoneOffset.ofHours(8)).toEpochMilli()); CmsContentQueryVo queryVo = new CmsContentQueryVo(); queryVo.setStatus(ContentStatus.PUBLISH); for (int i = 1;; i++) { dataPage.setPageNo(1); beginReleasedDate.add(Calendar.SECOND, 1); queryVo.setBeginReleasedDate(beginReleasedDate); DataPage<CmsContent> contentPage = cmsContentManager.queryByVo(dataPage, queryVo); logger.info("create page:{}, pageSize:{}, total:{}", i, contentPage.getPageSize(), contentPage.getTotalCount()); List<CmsContent> contents = contentPage.getDataList(); if (CollectionUtils.isEmpty(contents)) { break; } List<Long> contIdList = contents.stream().map(CmsContent::getId).collect(Collectors.toList()); List<CmsContentTxt> txtList = cmsContentTxtManager.query(contIdList); List<CmsContentStock> stockList = cmsContentStockManager.queryByContentIdList(contIdList); List<CmsContentTag> tagList = cmsContentTagManager.queryByIdList(contIdList); List<ContentIndex> indexs = new ArrayList<>(); for (CmsContent c : contents) { if (CollectionUtils.isNotEmpty(txtList)) { txtList.stream().filter(txt -> txt.getContentId().longValue() == c.getId().longValue()).findAny().ifPresent(txt -> { c.setContentTxt(txt.getTxt()); if (StringUtils.isEmpty(c.getDescription())) { String contTxt = Jsoup.parse(c.getContentTxt()).text(); String txtStr = contTxt.length() > 200 ? contTxt.substring(0, 200) : contTxt; c.setDescription(txtStr); } }); } if (CollectionUtils.isNotEmpty(tagList)) { List<String> tagStrList = tagList.stream().filter(tag -> tag.getContentId().longValue() == c.getId().longValue()) .map(CmsContentTag::getTagName).filter(StringUtils::isNotBlank).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(tagStrList) && tagStrList.toArray() != null && tagStrList.toArray() instanceof String[]) { c.setESTags((String[]) tagStrList.toArray()); } } if (CollectionUtils.isNotEmpty(stockList)) { List<String> stockStrList = stockList.stream().filter(stock -> stock.getContentId().longValue() == c.getId().longValue()) .map(CmsContentStock::getStockCode).filter(StringUtils::isNotBlank).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(stockStrList) && stockStrList.toArray() != null && stockStrList.toArray() instanceof String[]) { c.setESRelatedStocks((String[]) stockStrList.toArray()); } } ContentIndex index = new ContentIndex(c); indexs.add(index); } contentIndexRepository.save(indexs); beginReleasedDate = contents.get(contents.size() - 1).getReleasedDate(); } LocalDateTime endTime = LocalDateTime.now(); logger.info("初始化contentIndex结束,共耗时:{} min", String.valueOf(Duration.between(beginTime, endTime).toMinutes())); }); } private void helpCenterInit() { taskExecutor.execute(() -> { logger.info("初始化 help-center 开始"); LocalDateTime beginTime = LocalDateTime.now(); helpCenterRepository.deleteAll(); DataPage<CmsContent> dataPage = new DataPage<>(); dataPage.setPageSize(page_size); dataPage.setOrder("ASC"); dataPage.setOrderBy("released_date"); Calendar beginReleasedDate = Calendar.getInstance(); beginReleasedDate.set(1970, 10, 10, 10, 10, 10); CmsContentQueryVo queryVo = new CmsContentQueryVo(); queryVo.setStatus(ContentStatus.PUBLISH); ModelResult<List<CmsChannelDefine>> modelResult = cmsChannelDefineService .queryLastChildByChannel(ChannelDefineType.NEW_HELP_CENTER.getIndex().longValue()); List<CmsChannelDefine> cmsChannelDefines = modelResult.getModel(); List<Long> ids = new ArrayList<>(); cmsChannelDefines.stream().forEach(p -> { ids.add(p.getId()); }); logger.info("helpCenterInit ids:{}", ids.size()); for (int i = 1; ; i++) { dataPage.setPageNo(1); beginReleasedDate.add(Calendar.SECOND, 1); queryVo.setBeginReleasedDate(beginReleasedDate); queryVo.setChannelIds(ids); DataPage<CmsContent> contentPage = cmsContentManager.queryByVo(dataPage, queryVo); logger.info("helpCenterInit create page:{}, pageSize:{}, total:{}", i, contentPage.getPageSize(), contentPage.getTotalCount()); List<CmsContent> contents = contentPage.getDataList(); if (CollectionUtils.isEmpty(contents)) { break; } List<Long> contIdList = contents.stream() .map(CmsContent::getId) .collect(Collectors.toList()); List<CmsContentTxt> txtList = cmsContentTxtManager.query(contIdList); List<CmsContentStock> stockList = cmsContentStockManager.queryByContentIdList(contIdList); List<CmsContentTag> tagList = cmsContentTagManager.queryByIdList(contIdList); List<HelpCenterContentIndex> indexs = new ArrayList<>(); for(CmsContent c : contents) { if (CollectionUtils.isNotEmpty(txtList)) { txtList.stream() .filter(txt -> txt.getContentId().longValue() == c.getId().longValue()) .findAny() .ifPresent(txt -> { c.setContentTxt(txt.getTxt()); if (StringUtils.isEmpty(c.getDescription())) { String contTxt = Jsoup.parse(c.getContentTxt()).text(); String txtStr = contTxt.length() > 200 ? contTxt.substring(0, 200) : contTxt; c.setDescription(txtStr); } }); } if (CollectionUtils.isNotEmpty(tagList)) { List<String> tagStrList = tagList.stream() .filter(tag -> tag.getContentId().longValue() == c.getId().longValue()) .map(CmsContentTag::getTagName) .filter(StringUtils::isNotBlank) .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(tagStrList) && tagStrList.toArray() != null && tagStrList.toArray() instanceof String[]) { c.setESTags((String[]) tagStrList.toArray()); } } if (CollectionUtils.isNotEmpty(stockList)) { List<String> stockStrList = stockList.stream() .filter(stock -> stock.getContentId().longValue() == c.getId().longValue()) .map(CmsContentStock::getStockCode) .filter(StringUtils::isNotBlank) .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(stockStrList) && stockStrList.toArray() != null && stockStrList.toArray() instanceof String[]) { c.setESRelatedStocks((String[])stockStrList.toArray()); } } HelpCenterContentIndex index = new HelpCenterContentIndex(c); indexs.add(index); } helpCenterRepository.save(indexs); beginReleasedDate = contents.get(contents.size() - 1).getReleasedDate(); } LocalDateTime endTime = LocalDateTime.now(); logger.info("初始化helpCenterInit结束,共耗时:{} min", String.valueOf(Duration.between(beginTime, endTime).toMinutes())); }); } @Override public DataPage<ContentSearchResult> searchContentByKeyword(String keyword, List<String> filterField, DataPage<ContentSearchResult> dataPage) { DataPage<ContentSearchResult> reDataPage = contentIndexManager.searchContentByKeyword(keyword, filterField, dataPage); // if (dataPage.getPageNo() < 2) { // List<ContentSearchResult> dataList = dataPage.getDataList(); // if (CollectionUtils.isNotEmpty(dataList)) { // dataList.sort((c1, c2) -> c2.getReleasedDate().compareTo(c1.getReleasedDate())); // } // } return reDataPage; } @Override public List<ContentSearchResult> searchByKeyword(String keyword, int pageSize, int pageNo) { Objects.requireNonNull(keyword); return contentIndexManager.searchByKeyword(keyword, pageSize, pageNo); } @Override public DataPage<ContentSearchResult> searchContentByTags(DataPage<ContentSearchResult> dataPage, Long id, Long channelId, String[] tags) { return contentIndexManager.searchContentByTags(dataPage, id, channelId, tags); } @Override public DataPage<ContentSearchResult> searchContentByKeyword(String keyword, List<String> filterField, DataPage<ContentSearchResult> dataPage, String[] esIndexs, String[] esTypes) { return contentIndexManager.searchContentByKeyword(keyword, filterField, dataPage, esIndexs, esIndexs); } @Override public List<ContentSearchResult> searchByKeyword(String keyword, int pageSize, int pageNo, String[] esIndexs, String[] esTypes) { return contentIndexManager.searchByKeyword(keyword, pageSize, pageNo, esIndexs, esTypes); } @Override public DataPage<ContentSearchResult> searchContentByTags(DataPage<ContentSearchResult> dataPage, Long id, Long channelId, String[] tags, String[] esIndexs, String[] esTypes) { return contentIndexManager.searchContentByTags(dataPage, id, channelId, tags, esIndexs, esTypes); } }
package com.xxxx.cms.elasticsearch.manager.impl; import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termsQuery; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.search.SearchResponse; //import org.elasticsearch.common.base.Strings; import org.elasticsearch.common.text.Text; import org.elasticsearch.index.query.BoolQueryBuilder; //import org.elasticsearch.index.query.FilterBuilders; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.highlight.HighlightBuilder; import org.elasticsearch.search.highlight.HighlightField; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.stereotype.Repository; import com.xxxx.appmodel.domain.result.ModelResult; import com.xxxx.appmodel.page.DataPage; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.xxxx.cms.channel.common.domain.CmsChannelDefine; import com.xxxx.cms.channel.common.service.CmsChannelDefineService; import com.xxxx.cms.channel.common.type.ChannelDefineType; import com.xxxx.cms.channel.manager.CmsChannelDefineManager; import com.xxxx.cms.config.constant.BaseConstant; import com.xxxx.cms.content.common.domain.CmsContent; import com.xxxx.cms.content.common.domain.CmsContentTag; import com.xxxx.cms.content.common.type.ContentStatus; import com.xxxx.cms.content.common.utils.ContentFlagBitOperUtils; import com.xxxx.cms.content.manager.CmsContentTagManager; import com.xxxx.cms.elasticsearch.common.domain.ContentSearchResult; import com.xxxx.cms.elasticsearch.constant.CacheConstant; import com.xxxx.cms.elasticsearch.constant.ElasticSearchConstant; import com.xxxx.cms.elasticsearch.domain.ContentIndex; import com.xxxx.cms.elasticsearch.domain.HelpCenterContentIndex; import com.xxxx.cms.elasticsearch.manager.ContentIndexManager; import com.xxxx.cms.elasticsearch.repositories.ContentIndexRepository; import com.xxxx.cms.elasticsearch.repositories.HelpCenterRepository; import com.xxxx.cms.tag.common.domain.CmsTagInfo; import com.xxxx.cms.tag.common.service.CmsTagInfoService; import com.xxxx.cms.tag.common.type.TagInfoType; import redis.clients.jedis.JedisCluster; @Repository public class ContentIndexManagerImpl implements ContentIndexManager { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private ElasticsearchOperations elasticsearchTemplate; @Autowired private ContentIndexRepository contentIndexRepository; @Autowired private HelpCenterRepository helpCenterRepository; @Resource(name="cmsChannelDefineManager") private CmsChannelDefineManager cmsChannelDefineManager; @Resource(name="jedisClusterClient") private JedisCluster jedisClusterClient; @Autowired @Qualifier("cmsChannelDefineService") private CmsChannelDefineService cmsChannelDefineService; @Autowired @Qualifier("cmsTagInfoService") private CmsTagInfoService cmsTagInfoService; @Autowired private CmsContentTagManager cmsContentTagManager; protected static final String REDIS_CACHE_PREFIX = CacheConstant.ES_PREFIX + "ContentIndexManager" + BaseConstant.REDIS_CACHE_SEPERATOR; public static final String ID_FIELD = "id"; public static final String TITLE_FIELD = "title"; public static final String DESCRIPTION_FIELD = "description"; public static final String CONTENT_TXT_FIELD = "contentTxt"; public static final String RELEASED_DATE_FIELD = "releasedDate"; public static final String CHANNEL_ID_FIELD = "channelId"; public static final String STATUS_FIELD = "status"; public static final String FLAG_BIT_FIELD = "flagBit"; public static final String TAGS_FIELD = "tags"; public static final String RELATED_STOCKS_FIELD = "relatedStocks"; public static final String ANALYZER_NAME = "ik"; @Override public void createCmsContentIndex(CmsContent cmsContent) { ContentIndex snsMsgIndex = new ContentIndex(cmsContent); contentIndexRepository.save(snsMsgIndex); } @Override public DataPage<ContentSearchResult> searchContentByKeyword(String keyword, List<String> filterField, DataPage<ContentSearchResult> dataPage) { return searchContentByKeyword(keyword, filterField, dataPage, null, null); } @Override public List<ContentSearchResult> searchByKeyword(String keyword, int pageSize, int pageNo) { List<ContentSearchResult> searchList = searchByKeyword(keyword, pageSize, pageNo, null, null); //投教标签 setupHelpTag(searchList); return searchList; } private void setupHelpTag(List<ContentSearchResult> searchList) { if (!CollectionUtils.isEmpty(searchList)) { // 查询各篇文章关联的投教标签 List<CmsTagInfo> helpTagList = cmsTagInfoService.queryChildrenByParentId(TagInfoType.HELP_TAG.getIndex()); List<Integer> idList = helpTagList.stream().map(CmsTagInfo::getId).collect(Collectors.toList()); List<Long> contentIdList = searchList.stream().map(ContentSearchResult::getId).collect(Collectors.toList()); Map<String, Object> param = new HashMap<>(); param.put("contentIdList", contentIdList); param.put("tagIdList", idList); List<CmsContentTag> contentTagList = cmsContentTagManager.query(param); Map<Long,List<CmsContentTag>> tagListMap = new HashMap<>(); if (!CollectionUtils.isEmpty(contentTagList)) { for (CmsContentTag tag : contentTagList) { List<CmsContentTag> tagList = tagListMap.get(tag.getContentId()); if (tagList == null) { tagList = new ArrayList<CmsContentTag>(); } tagList.add(tag); tagListMap.put(tag.getContentId(), tagList); } } for (ContentSearchResult content : searchList) { if (tagListMap.get(content.getId()) == null) { content.setTagList(new ArrayList<>()); } else { content.setTagList(tagListMap.get(content.getId())); } } } } @Override public DataPage<ContentSearchResult> searchContentByTags(DataPage<ContentSearchResult> dataPage, Long id, Long channelId, String[] tags) { return searchContentByTags(dataPage, id, channelId, tags , null , null); } @Override public DataPage<ContentSearchResult> searchContentByKeyword(String keyword, List<String> filterField, DataPage<ContentSearchResult> dataPage, String [] esIndexs, String [] esTypes) { logger.info("执行搜索:{}", keyword); NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withIndices(esIndexs == null || esIndexs.length == 0 ? new String[] { ElasticSearchConstant.CMS_INDEX } : esIndexs) .withTypes(esTypes == null || esTypes.length == 0 ? new String[] { ElasticSearchConstant.CMS_CONTENT_TYPE } : esTypes); LocalDateTime todayBeginTime = LocalDate.now().atTime(0, 0, 0), todayEndTime = LocalDate.now().atTime(23, 59, 59), now = LocalDateTime.now(); final BoolQueryBuilder boolQuery = boolQuery(); if (CollectionUtils.isEmpty(filterField)) { boolQuery.should(termQuery(TITLE_FIELD, keyword)); boolQuery.should(matchPhraseQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).slop(1)); boolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME)); // 控制内容的相关度 BoolQueryBuilder txtQuery = boolQuery(); txtQuery.should(matchPhraseQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).slop(5)); txtQuery.should(matchQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).minimumShouldMatch("30%")); boolQuery.should(txtQuery); boolQuery.must(multiMatchQuery(keyword, DESCRIPTION_FIELD + "^2", TAGS_FIELD, RELATED_STOCKS_FIELD) .type(Type.CROSS_FIELDS) .analyzer(ANALYZER_NAME)); } else { if (filterField.contains(TITLE_FIELD)) { boolQuery.should(termQuery(TITLE_FIELD, keyword)); boolQuery.should(matchPhraseQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).slop(3)); // boolQuery.should(matchQuery(TITLE_FIELD, keyword).operator(Operator.AND).analyzer(WORD_SEPERATOR_NAME)); boolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).boost(1.2f)); } if (filterField.contains(DESCRIPTION_FIELD)) { BoolQueryBuilder descBoolQuery = boolQuery(); descBoolQuery.should(matchPhraseQuery(DESCRIPTION_FIELD, keyword).analyzer(ANALYZER_NAME).slop(3)); descBoolQuery.should(matchQuery(DESCRIPTION_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(descBoolQuery); } if (filterField.contains(CONTENT_TXT_FIELD)) { boolQuery.should(matchPhraseQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).slop(5)); boolQuery.should(matchQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).minimumShouldMatch("20%")); } if (filterField.contains(TAGS_FIELD)) { boolQuery.should(matchPhraseQuery(TAGS_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(matchQuery(TAGS_FIELD, keyword).analyzer(ANALYZER_NAME)); } if (filterField.contains(RELATED_STOCKS_FIELD)) { boolQuery.should(matchPhraseQuery(RELATED_STOCKS_FIELD, keyword).analyzer(ANALYZER_NAME)); } } this.general4PeriodQuery(boolQuery, todayBeginTime); this.general4ChannelQuery(boolQuery); nativeSearchQueryBuilder.withQuery(boolQuery); String cacheKey = REDIS_CACHE_PREFIX + "searchContentByKeyword" + BaseConstant.REDIS_CACHE_SEPERATOR + "investmentChannelList", cacheStr = jedisClusterClient.get(cacheKey); // 缓存60分钟 int cacheSecond = 60 * 60; ArrayList<Long> searchChanList = new ArrayList<>(); List<Long> investmentChanList = null; if (StringUtils.isNotEmpty(cacheStr)) { investmentChanList = JSONArray.parseArray(cacheStr, Long.class); searchChanList.addAll(investmentChanList); } else { List<CmsChannelDefine> investmentChannelList = cmsChannelDefineManager .selectAllChildInvestmentChannel(ChannelDefineType.INVESTMENT_CHANNEL.getIndex().longValue()); if (CollectionUtils.isNotEmpty(investmentChannelList)) { investmentChanList = investmentChannelList.stream() .filter(CmsChannelDefine::getIsDisplay) .map(CmsChannelDefine::getId) .collect(Collectors.toList()); cacheStr = JSON.toJSONString(investmentChanList); jedisClusterClient.setex(cacheKey, cacheSecond, cacheStr); searchChanList.addAll(investmentChanList); } } searchChanList.addAll( Arrays.asList( ChannelDefineType.COMB_CHANNEL.getIndex().longValue(), ChannelDefineType.CHINESE_STOCK_CHANNEL.getIndex().longValue(), ChannelDefineType.SINAFIN_CHANNEL.getIndex().longValue(), ChannelDefineType.ZHITONGFIN_YW_CHANNEL.getIndex().longValue() ) ); this.general4FilterOper(nativeSearchQueryBuilder, searchChanList, todayBeginTime, todayEndTime); this.general4HighLightOper(nativeSearchQueryBuilder, keyword); this.general4PageOper(nativeSearchQueryBuilder, dataPage.getPageNo() - 1, dataPage.getPageSize()); // nativeSearchQueryBuilder.withSearchType(SearchType.DFS_QUERY_THEN_FETCH);// 默认是query then fetch,使用默认查询方式 SearchQuery searchQuery = nativeSearchQueryBuilder.build(); // Long totalCount = elasticsearchTemplate.count(searchQuery, ContentIndex.class); List<ContentSearchResult> contentIndexList = this.generalQueryExtractOper(searchQuery); // List<ContentSearchResult> contentIndexList = elasticsearchTemplate.queryForList(searchQuery, ContentSearchResult.class); dataPage.setDataList(contentIndexList); // dataPage.setTotalCount(totalCount); dataPage.setTotalCount(100); LocalDateTime excuteEndTime = LocalDateTime.now(); logger.info("搜索执行时间:{}毫秒", Duration.between(now, excuteEndTime).toMillis()); return dataPage; } private BoolQueryBuilder general4PeriodQuery(final BoolQueryBuilder boolQuery, LocalDateTime todayBeginTime) { LocalDateTime now = LocalDateTime.now(); LocalDateTime threeDaysAgo = todayBeginTime.minusDays(3L), oneWeekAgo = todayBeginTime.minusWeeks(1L), threeMonthsAgo = todayBeginTime.minusMonths(3L), halfOfYearAgo = todayBeginTime.minusMonths(6L); // 3天内的资讯相关度更高 boolQuery.should(rangeQuery(RELEASED_DATE_FIELD) .gt(threeDaysAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .lte(now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .boost(15f)); // 一周内的资讯相关度更高 boolQuery.should(rangeQuery(RELEASED_DATE_FIELD) .gt(oneWeekAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .lte(threeDaysAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .boost(10f)); // 3个月内的资讯相关度更高 boolQuery.should(rangeQuery(RELEASED_DATE_FIELD) .gt(threeMonthsAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .lte(oneWeekAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli())); // 半年以前的相关度降低 boolQuery.should(rangeQuery(RELEASED_DATE_FIELD) .lte(halfOfYearAgo.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .boost(0.6f)); return boolQuery; } private BoolQueryBuilder general4ChannelQuery(final BoolQueryBuilder boolQuery) { // 提高个股资讯的相关度 // boolQuery.should(termQuery(CHANNEL_ID_FIELD, ChannelDefineType.CHINESE_STOCK_CHANNEL.getIndex().longValue())); // 提高自产相关度 // boolQuery.should(termQuery(CHANNEL_ID_FIELD, ChannelDefineType.COMB_CHANNEL.getIndex().longValue())); // 由于暂时不知道ES是否支持位操作,就从业务角度上来说给一个具体值就算了 boolQuery.should(termQuery(FLAG_BIT_FIELD, ContentFlagBitOperUtils.HELP_CENTER_VAL).boost(1.6f)); return boolQuery; } private NativeSearchQueryBuilder general4QueryOper(final NativeSearchQueryBuilder natvSechQBuilder, String keyword, LocalDateTime todayBeginTime) { final BoolQueryBuilder boolQuery = boolQuery(); String minimumShouldMatchStrategy = "3<75%"; // boolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME)); // boolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).operator(Operator.AND)); // boolQuery.should(multiMatchQuery(keyword, DESCRIPTION_FIELD, CONTENT_TXT_FIELD).tieBreaker(0.4f).minimumShouldMatch(minimumShouldMatchStrategy)); // DisMaxQueryBuilder titleAndDescrptionMaxQuery = disMaxQuery().add(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME)) // .add(matchQuery(DESCRIPTION_FIELD, keyword).analyzer(ANALYZER_NAME)) // .tieBreaker(0.4f) // .queryName("disMaxQueryTest"); // boolQuery.should(titleAndDescrptionMaxQuery); // boolQuery.should(termQuery(TITLE_FIELD, keyword).boost(5f)); boolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(matchPhraseQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).type(MatchQueryBuilder.Type.PHRASE_PREFIX).boost(5f)); BoolQueryBuilder titleBoolQuery = boolQuery(); titleBoolQuery.should(termQuery(TITLE_FIELD, keyword)); titleBoolQuery.should(matchPhraseQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).slop(1)); // boolQuery.should(matchPhrasePrefixQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME).slop(10).maxExpansions(20)); titleBoolQuery.should(matchQuery(TITLE_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(titleBoolQuery); BoolQueryBuilder descBoolQuery = boolQuery(); descBoolQuery.should(matchPhraseQuery(DESCRIPTION_FIELD, keyword).analyzer(ANALYZER_NAME)); descBoolQuery.should(matchQuery(DESCRIPTION_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(descBoolQuery); // multiMatchQuery(DESCRIPTION_FIELD, keyword).type(MultiMatchQueryBuilder.Type.MOST_FIELDS); boolQuery.should(matchPhraseQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(matchQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME)); BoolQueryBuilder contTxtBoolQuery = boolQuery(); contTxtBoolQuery.should(matchPhraseQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).slop(2).minimumShouldMatch(minimumShouldMatchStrategy)); // contTxtBoolQuery.should(matchPhraseQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME).slop(2)); contTxtBoolQuery.should(matchQuery(CONTENT_TXT_FIELD, keyword).analyzer(ANALYZER_NAME)); boolQuery.should(contTxtBoolQuery); this.general4ChannelQuery(boolQuery); this.general4PeriodQuery(boolQuery, todayBeginTime); natvSechQBuilder.withQuery(boolQuery); return natvSechQBuilder; } private NativeSearchQueryBuilder general4FilterOper(final NativeSearchQueryBuilder natvSechQBuilder, ArrayList<Long> searchChanlList, LocalDateTime todayBeginTime, LocalDateTime todayEndTime) { BoolQueryBuilder filterQuery = boolQuery(); // 只搜索12个月内的资讯信息 LocalDateTime searchStartTime = todayBeginTime.minusMonths(12L); filterQuery.must(rangeQuery(RELEASED_DATE_FIELD) .gte(searchStartTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .lte(todayEndTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli())); if (CollectionUtils.isNotEmpty(searchChanlList)) { filterQuery.must(termsQuery(CHANNEL_ID_FIELD, searchChanlList.toArray())); } filterQuery.must(termQuery(STATUS_FIELD, ContentStatus.PUBLISH.getIndex().intValue())); natvSechQBuilder.withFilter(filterQuery); return natvSechQBuilder; } private NativeSearchQueryBuilder general4HighLightOper(final NativeSearchQueryBuilder natvSechQBuilder, String keyword) { String preTagStr = "<font color=#ff8200>", postTagStr = "</font>"; HighlightBuilder.Field title = new HighlightBuilder.Field(TITLE_FIELD); title.preTags(preTagStr); title.postTags(postTagStr); HighlightBuilder.Field des = new HighlightBuilder.Field(DESCRIPTION_FIELD); des.preTags(preTagStr); des.postTags(postTagStr); natvSechQBuilder.withHighlightFields(title, des); return natvSechQBuilder; } private NativeSearchQueryBuilder general4PageOper(final NativeSearchQueryBuilder natvSechQBuilder, int pageNo, int pageSize) { // spring data的接口是从第0页开始,不要问我为什么 natvSechQBuilder.withPageable(new PageRequest(pageNo, pageSize)); natvSechQBuilder.withMinScore(0.5f);// 相关度不低于50% return natvSechQBuilder; } private List<ContentSearchResult> generalQueryExtractOper(final SearchQuery searchQuery) { return elasticsearchTemplate.query(searchQuery, (SearchResponse response) -> { List<ContentSearchResult> results = new ArrayList<ContentSearchResult>(); for (SearchHit hit : response.getHits()) { ContentSearchResult result = JSON.parseObject(hit.getSourceAsString(), ContentSearchResult.class); Map<String, HighlightField> hlFields = hit.getHighlightFields(); HighlightField titleHLField = hlFields.get(TITLE_FIELD); if (titleHLField != null) { // 取得定义的高亮标签 Text[] titleTexts = titleHLField.getFragments(); // 为title串值增加自定义的高亮标签 String titleStr = ""; for (Text text : titleTexts) { titleStr += text; } // 将追加了高亮标签的串值重新填充到对应的对象 result.setTitle(titleStr); } // 从设定的高亮域中取得指定域 HighlightField descHLField = hlFields.get(DESCRIPTION_FIELD); if (descHLField != null) { // 取得定义的高亮标签 Text[] descTexts = descHLField.fragments(); // 为title串值增加自定义的高亮标签 String desc = ""; for (Text text : descTexts) { desc += text; } // 将追加了高亮标签的串值重新填充到对应的对象 result.setDescription(desc); } logger.info("contentId:{}", result.getId()); results.add(result); } return results; }); } @Override public List<ContentSearchResult> searchByKeyword(String keyword, int pageSize, int pageNo, String[] esIndexs, String[] esTypes) { logger.info("searchByKeywords => 搜索关键词:【{}】 => 开始", keyword); LocalDateTime todayBeginTime = LocalDate.now().atStartOfDay(), todayEndTime = todayBeginTime.plusDays(1L).minusSeconds(1L), now = LocalDateTime.now(); NativeSearchQueryBuilder natvSechQBuilder = new NativeSearchQueryBuilder(); esIndexs = esIndexs == null ? new String[] { ElasticSearchConstant.CMS_INDEX } : esIndexs; esTypes = esTypes == null ? new String[] { ElasticSearchConstant.CMS_CONTENT_TYPE } : esTypes; natvSechQBuilder.withIndices(esIndexs).withTypes(esTypes); // this.general4QueryParam(natvSechQBuilder, keyword, todayBeginTime);// 实用但不直观的写法 natvSechQBuilder = this.general4QueryOper(natvSechQBuilder, keyword, todayBeginTime); String cacheKey = REDIS_CACHE_PREFIX + "searchContentByKeyword" + BaseConstant.REDIS_CACHE_SEPERATOR + "investmentChannelList", cacheStr = jedisClusterClient.get(cacheKey); // 缓存60分钟 int cacheSecond = 60 * 60; ArrayList<Long> searchChanlList = new ArrayList<>(); esTypes = new String[] { ElasticSearchConstant.CMS_CONTENT_TYPE, ElasticSearchConstant.CMS_HELP_CENTER_TYPE };// 过滤时增加帮助中心 for (int i = 0; i < esTypes.length; i++) { String types = esTypes[i]; if (types.equals(ElasticSearchConstant.CMS_CONTENT_TYPE)) { List<Long> investCollegeChanlIdList = null; if (StringUtils.isNotEmpty(cacheStr)) { investCollegeChanlIdList = JSONArray.parseArray(cacheStr, Long.class); searchChanlList.addAll(investCollegeChanlIdList); } else { List<CmsChannelDefine> investCollegeChnlList = cmsChannelDefineManager .selectAllChildInvestmentChannel(ChannelDefineType.INVESTMENT_CHANNEL.getIndex().longValue()); if (CollectionUtils.isNotEmpty(investCollegeChnlList)) { investCollegeChanlIdList = investCollegeChnlList.stream() .filter(CmsChannelDefine::getIsDisplay) .map(CmsChannelDefine::getId) .collect(Collectors.toList()); cacheStr = JSON.toJSONString(investCollegeChanlIdList); jedisClusterClient.setex(cacheKey, cacheSecond, cacheStr); searchChanlList.addAll(investCollegeChanlIdList); } } searchChanlList.addAll( Arrays.asList(ChannelDefineType.COMB_CHANNEL.getIndex().longValue(), ChannelDefineType.CHINESE_STOCK_CHANNEL.getIndex().longValue(), ChannelDefineType.SINAFIN_CHANNEL.getIndex().longValue(), ChannelDefineType.ZHITONGFIN_YW_CHANNEL.getIndex().longValue())); } else if (types.equals(ElasticSearchConstant.CMS_HELP_CENTER_TYPE)) { String cmsCacheKey = cacheKey + "cmshelpcenter"; cacheStr = jedisClusterClient.get(cmsCacheKey); List<Long> cmsHelpCenterLastChild = null; if (StringUtils.isNotEmpty(cacheStr)) { cmsHelpCenterLastChild = JSONArray.parseArray(cacheStr, Long.class); searchChanlList.addAll(cmsHelpCenterLastChild); } else { ModelResult<List<CmsChannelDefine>> listModelResult = cmsChannelDefineService .queryAllChildByParentId(ChannelDefineType.NEW_HELP_CENTER.getIndex().longValue()); List<CmsChannelDefine> cmsChannelDefines = listModelResult.getModel(); if (CollectionUtils.isNotEmpty(cmsChannelDefines)) { cmsHelpCenterLastChild = cmsChannelDefines.stream() .filter(CmsChannelDefine::getIsDisplay) .map(CmsChannelDefine::getId) .collect(Collectors.toList()); cacheStr = JSON.toJSONString(cmsHelpCenterLastChild); jedisClusterClient.setex(cacheKey, cacheSecond, cacheStr); searchChanlList.addAll(cmsHelpCenterLastChild); } } } } // this.general4FilterParam(natvSechQBuilder, searchChanlList, todayBeginTime, todayEndTime);// 实用但不直观的写法 natvSechQBuilder = this.general4FilterOper(natvSechQBuilder, searchChanlList, todayBeginTime, todayEndTime); // this.generalHighLightOper(natvSechQBuilder, keyword, pageNo, pageSize);// 实用但不直观的写法 natvSechQBuilder = this.general4HighLightOper(natvSechQBuilder, keyword); // this.general4PageOper(natvSechQBuilder, pageNo, pageSize);// 实用但不直观的写法 natvSechQBuilder = this.general4PageOper(natvSechQBuilder, pageNo, pageSize); // nativeSearchQueryBuilder.withSearchType(SearchType.DFS_QUERY_THEN_FETCH);// 默认是query then fetch,使用默认查询方式 SearchQuery searchQuery = natvSechQBuilder.build(); Sort sort = new Sort(Direction.DESC, RELEASED_DATE_FIELD); searchQuery.addSort(sort); List<ContentSearchResult> searchResults = this.generalQueryExtractOper(searchQuery); LocalDateTime excuteEndTime = LocalDateTime.now(); logger.info("搜索执行时间:{}毫秒", Duration.between(now, excuteEndTime).toMillis()); return searchResults; } @Override public DataPage<ContentSearchResult> searchContentByTags(DataPage<ContentSearchResult> dataPage, Long id, Long channelId, String[] tags, String[] esIndexs, String[] esTypes) { NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withIndices(esIndexs == null || esIndexs.length == 0 ? new String[] { ElasticSearchConstant.CMS_INDEX } : esIndexs) .withTypes(esTypes == null || esTypes.length == 0 ? new String[] { ElasticSearchConstant.CMS_CONTENT_TYPE } : esTypes); BoolQueryBuilder boolQuery = boolQuery(); for (String tag : tags) { boolQuery.should(matchPhraseQuery(TAGS_FIELD, tag)); } //MatchQueryBuilder matchBuilder=new MatchQueryBuilder("channelId", channelId); MatchQueryBuilder matchBuilderId = new MatchQueryBuilder(ID_FIELD, id); //boolQuery.must(matchBuilder); boolQuery.mustNot(matchBuilderId); /* TermsQueryBuilder termsQuery = new TermsQueryBuilder("channelId",channelId+""); boolQuery.must(termsQuery);*/ // TODO nativeSearchQueryBuilder.withFilter(QueryBuilders.termQuery(CHANNEL_ID_FIELD, channelId)); // nativeSearchQueryBuilder // .withFilter(FilterBuilders.andFilter(FilterBuilders.termFilter("channelId", channelId))); this.general4PageOper(nativeSearchQueryBuilder, dataPage.getPageNo() - 1, dataPage.getPageSize()); nativeSearchQueryBuilder.withQuery(boolQuery); SearchQuery searchQuery = nativeSearchQueryBuilder.build(); Sort sort = new Sort(Direction.DESC, RELEASED_DATE_FIELD); searchQuery.addSort(sort); Long totalCount = elasticsearchTemplate.count(searchQuery, ContentIndex.class); List<ContentSearchResult> contentIndexList = elasticsearchTemplate.queryForList(searchQuery, ContentSearchResult.class); dataPage.setDataList(contentIndexList); dataPage.setTotalCount(totalCount); return dataPage; } @Override public void createHelpCenterContentIndex(CmsContent cmsContent) { HelpCenterContentIndex helpCenterContentIndex = new HelpCenterContentIndex(cmsContent); helpCenterRepository.save(helpCenterContentIndex); } }
发表评论
-
简单的压测模拟
2018-05-11 19:52 675import java.time.Duration; i ... -
Java的驼峰与下划线的属性对象互相转换
2018-05-11 19:50 8426import com.xxxx.util.consta ... -
针对基于Redis Cluster的接口数据缓存删除实现
2018-03-26 10:35 1249首先定义个工具interface,基于Java 8的实现. 主 ... -
简单ELK配合logback搭建日志监控中心
2018-03-20 17:30 1348今天得闲就自己搭了个ELK示例,过程挺简单的。 Elas ... -
spring的基于java的项目配置示例2
2018-03-20 17:32 852import com.xxx.support.config ... -
HttpClient实例
2018-03-16 08:15 664import java.io.IOException; ... -
spring的基于java的项目配置示例1
2018-03-16 08:26 941spring的基于java的项目配置示例。 impor ... -
基于spring data的Elastic Search的配置示例
2018-03-15 17:41 915基于spring data的Elastic Search的配置 ... -
方便jedis cluster操作的工具类
2018-03-15 17:37 3029由于redis的集群 redis cluster不支持keys ... -
爬虫基础类
2018-03-15 17:28 810自己封装的爬虫基础类。 public interfac ... -
基于AOP的ajax的referrer判断
2018-03-15 17:23 1564网页中ajax请求的referrer的值是当前域名。(其实这个 ... -
Java Timestamp从MySQL数据库取出的字符串转换为LocalDateTime
2016-01-26 16:08 9931最新在工作中使用了Java 8的LocalDate ... -
reviewC指针
2014-03-02 22:05 372由于要考试,有C的考核内容。所以今天把C拉出来又看了下,其实基 ... -
Python2.X内置函数学习
2013-12-19 21:52 11711.apply()函数 学过Python的都知道P ... -
学习Python中遇到的问题
2013-09-04 23:26 721最近学习Python中。 先上代码: # -*- codi ...
相关推荐
Elasticsearch 7.0 实例精解源代码是一份深度解析Elasticsearch 7.0版本核心功能和实际应用的资源集合。这份压缩包包含了详细的示例代码,旨在帮助开发者更好地理解和掌握Elasticsearch的强大功能。以下是基于...
Java实现Elasticsearch的简单实例主要涉及以下几个关键知识点: 1. **Elasticsearch基础**:Elasticsearch(ES)是一个开源的、分布式全文搜索引擎,它提供了实时数据分析的能力,广泛用于日志分析、监控、搜索应用...
这个名为"基于.netcore搜索封装ElasticSearch.zip"的压缩包,显然包含了一个针对.NET Core平台的Elasticsearch客户端库,方便开发者在.NET Core应用中集成和操作Elasticsearch。 Elasticsearch是一个开源的分布式...
**Elasticsearch 集成 Spring 开发实例详解** 在现代大数据分析和实时搜索领域,Elasticsearch(简称 ES)已经成为了广泛使用的工具。它是一个分布式、RESTful 风格的搜索和数据分析引擎,能够处理大量数据并提供...
要使用Python处理Elasticsearch实例,可以使用elasticsearch库来与Elasticsearch进行交互。以下是一个简单的描述: 导入相关库:首先需要导入必要的Python库,如elasticsearch(用于与Elasticsearch建立连接和执行...
本篇文章将详细探讨如何在C#中使用Elasticsearch,并通过代码实例来展示其基本操作。 首先,安装Nest或Elasticsearch.Net库。在Visual Studio中,可以利用NuGet包管理器或命令行工具dotnet add package命令安装Nest...
Node是Elasticsearch中的单个实例,可以单独运行,也可以在集群中作为数据节点或协调节点。Cluster是由多个Node组成的,每个Cluster都有一个唯一的集群名称,默认为"elasticsearch"。Index是Elasticsearch中管理数据...
Spring Boot简化了Java应用程序的开发过程,而Elasticsearch则是一个强大的分布式搜索引擎。这个压缩包文件"springboot-elasticSearch"似乎提供了一个预配置的项目,允许开发者快速集成这两者,实现高效的全文搜索...
Elasticsearch是一款强大的开源搜索引擎,广泛应用于大数据分析和实时搜索领域。它基于Lucene库,提供了分布式、全文检索、近实时...在实际使用中,确保正确配置和管理Elasticsearch实例,是实现高效搜索和分析的关键。
这是最近在学习ElasticSearch的过程中,自己练习和积累的一些Java代码,使用ElasticSearch5.1.1版本 + IntelliJ IDEA开发,在代码中调用了ElasticSearch5.1.1中的最新的API。
本书以实例讲述如何在Spring框架之上搭建ElasticSearch开发,以及如何利用JPA建立、更新和删除索引,如何配置ElasticSearch Server的applicationContext等。
它基于Elasticsearch-Head或者Kibana的Dev Tools Console概念,但是增加了同时连接和管理多个Elasticsearch实例或集群的能力。这意味着用户可以通过一个统一的界面执行搜索、浏览索引、管理文档、监控集群状态以及...
Elasticsearch实例代码,简单演示Elasticsearch5.5下建立索引,查询,删除等操作。
6. **多租户**:一个Elasticsearch实例可以支持多个索引,每个索引有自己的设置和映射,实现资源隔离。 **Elasticsearch 7.17.10的新特性和改进:** 1. **性能优化**:此版本可能包含了针对查询速度、索引速度以及...
Elasticsearch是一款高性能的开源搜索引擎,特别适合进行全文检索。它基于Lucene库,但提供了更高级别的API和集群管理功能。在博客系统中,Elasticsearch可以存储和索引博客文章内容,以便快速地进行关键词搜索。 ...
这对于负责管理Elasticsearch实例的开发者和运维人员来说至关重要。 值得注意的是,本书适合那些已经具备一定编程和服务器管理经验的读者。作者通过具体案例和代码示例,帮助读者更好地理解和应用Elasticsearch的...
Elasticsearch是一个强大的开源搜索引擎,基于Lucene,它提供了分布式、实时、可扩展的数据存储和检索功能。在Java环境中操作Elasticsearch,我们通常会利用官方提供的Java API,这是一个非常全面且强大的工具集,让...
Elasticsearch是目前广泛应用的开源搜索引擎和分析引擎,尤其在日志分析、全文检索、实时数据存储等领域有着显著的优势。而`go-elasticsearch`则是Elasticsearch官方提供的用Go语言编写的客户端库,它为Go开发者提供...