上篇ES系列一之java端API操作結束後本以為就相安無事了,但生產的問題是層出不窮的;下面我就再記錄下近幾周遇到的問題以及解決方案;
報錯資訊如下:
Use ElasticsearchException.getFailedDocuments() for detailed messages [{yjZ8D0oB=ElasticsearchException[Elasticsearch exception [type=cluster_block_exception, reason=index [au_report] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];]]
分析:看報錯資訊大概意思就是es的寫入操作被阻塞了,索引只能讀、刪不能修改新增了;我總結了這種錯誤的解決方案以及步驟,如下:
curl --location --request PUT 'http://127.0.0.1:9200/au_report/_settings' \
--header 'Content-Type: application/json' \
--data-raw '{
"index.blocks.read_only_allow_delete": null
}'
read_only_allow_delete表示es唯讀和允許刪除不能做修改操作,當磁碟空間達到95%時自動為true;
curl --location --request GET 'http://127.0.0.1:9200/_cat/allocation?v'
我使用的spring-data-elasticsearch的版本是4.3.4,其實只要在ES系列一之java端API操作;分頁查詢的測試方法queryPageData()基礎上新增HighlightBuilder
設定需要高亮的欄位然後設定到返回結果去即可,下面貼上查詢程式碼:
@Test
public void queryPageData(){
// 此處應是查詢引數,這裡單元測試沒有賦值
TestQuery query = new TestQuery();
query.setTextKey("張三");
PaginationModel<EsTestInfo> res = new PaginationModel<>();
int currentPage=query.getPageIndex()-1;
int pageSize = query.getPageSize();
PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
BoolQueryBuilder textKeyBqb = new BoolQueryBuilder();
if (StringUtils.isNotBlank(query.getTextKey())) {
/**
* 由於下面會用到must查詢,所以此處用textKeyBqb再封裝一個builder出來,否則
* 和must同時查詢此處會出現0匹配也返回結果的情況
* 如果不想封裝textKeyBqb,加上boolQueryBuilder.minimumShouldMatch(1)強制使es
* 最少滿足一個should子句才能返回結果也行
*/
textKeyBqb.should(QueryBuilders.matchQuery("id", query.getTextKey()))
.should(QueryBuilders.matchQuery("name", query.getTextKey()))
.should(QueryBuilders.matchQuery("desc", query.getTextKey()));
}
if (Objects.nonNull(query.getStartDate()) && Objects.nonNull(query.getEndDate())) {
RangeQueryBuilder timeRangeQuery = QueryBuilders.rangeQuery("publishDt")
.gte(query.getStartDate().getTime())
.lte(query.getEndDate().getTime());
boolQueryBuilder.must(timeRangeQuery);
}
if (Objects.nonNull(query.getRptStatus())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("rptStatus", query.getRptStatus()));
}
// 將上面封裝的子句加入到主查詢條件中
boolQueryBuilder.must(textKeyBqb);
log.info("<<<<<<<<<<<<<<<<<<boolQueryBuilder:{}",boolQueryBuilder);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder).withPageable(pageRequest)
// 設定需要高亮的欄位
.withHighlightFields(
new HighlightBuilder.Field("name")
,new HighlightBuilder.Field("desc"))
// 設定高亮的html格式
.withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).build();
// 解決es一次只返回10000條資料的問題
searchQuery.setTrackTotalHits(true);
SearchHits<EsTestInfo> search = elasticsearchRestTemplate.search(searchQuery, EsTestInfo.class);
List<EsTestInfo> list = new ArrayList<>();
for (SearchHit<EsTestInfo> productSearchHit : search) {
EsTestInfo pro = productSearchHit.getContent();
//獲取高亮的欄位集合
Map<String, List<String>> highlightFields = productSearchHit.getHighlightFields();
//將高亮的內容填充到pro中
pro.setName(highlightFields.get("name")==null ? pro.getName():highlightFields.get("name").get(0));
pro.setDesc(highlightFields.get("desc")==null ? pro.getDesc():highlightFields.get("desc").get(0));
System.out.println("pro = " + pro);
list.add(pro);
}
res.setList(list);
res.setTotal(search.getTotalHits());
res.setPageIndex(query.getPageIndex());
res.setPageSize(query.getPageSize());
System.out.println("res = " + res);
}
測試結果如下:
這次更新的問題到此結束,後續遇到新的問題會繼續補充......