直接忽略安裝教程,網上一搜一大把,安裝起來也比較簡單。但是網上對于Java RestClient 能夠內建很好的沒有。接下來我将根據官方API內建了一套Java RestClient API操作模闆。
環境說明:
SpringBoot2.1.3 + JDK1.8 + Maven(Springboot自帶不好使用,建議按照自己的方式封裝)
需要源代碼的可以加我微信[JornTang]
application.yml
elasticsearch:
# ip位址,多個使用,分隔
ipAddrs: 127.0.0.1:9200,127.0.0.1:9201
client:
# 連接配接目标url最大逾時
connectTimeOut: 5000
# 等待響應(讀資料)最大逾時
socketTimeOut: 6000
# 從連接配接池中擷取可用連接配接最大逾時時間
connectionRequestTime: 3000
# 連接配接池中的最大連接配接數
maxConnectNum: 30
# 連接配接同一個route最大的并發數
maxConnectPerRoute: 10
pom.xml
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.0.1</version>
</dependency>
直接上代碼。【ps: 代碼待重構】
1、建立RestClientConfig配置類
@Configuration
public class RestClientConfig {
@Value("${elasticsearch.ipAddrs}")
private String[] ipAddrs;
@Value("${elasticsearch.client.connectTimeOut}")
private Integer connectTimeOut;
@Value("${elasticsearch.client.socketTimeOut}")
private Integer socketTimeOut;
@Value("${elasticsearch.client.connectionRequestTime}")
private Integer connectionRequestTime;
@Value("${elasticsearch.client.maxConnectNum}")
private Integer maxConnectNum;
@Value("${elasticsearch.client.maxConnectPerRoute}")
private Integer maxConnectPerRoute;
@Bean
public HttpHost[] httpHost(){
HttpHost[] httpHosts = new HttpHost[ipAddrs.length];
for (int i = 0; i < ipAddrs.length; i++) {
String[] ipAddr = ipAddrs[i].split(":");
httpHosts[i] = new HttpHost(ipAddr[0], Integer.valueOf(ipAddr[1]), "http");
}
return httpHosts;
}
@Bean(initMethod="init",destroyMethod="close")
public ElasticRestClientFactory getFactory(){
return ElasticRestClientFactory.
build(httpHost(), connectTimeOut, socketTimeOut, connectionRequestTime, maxConnectNum, maxConnectPerRoute);
}
@Bean
@Scope("singleton")
public RestClient getRestClient(){
return getFactory().getClient();
}
@Bean
@Scope("singleton")
public RestHighLevelClient getRestHighClient(){
return getFactory().getRestHighClient();
}
}
2、建立ElasticRestClientFactory工廠類
public class ElasticRestClientFactory {
private static Logger log = LoggerFactory.getLogger(ElasticRestClientFactory.class);
// 連接配接目标url最大逾時
public static int CONNECT_TIMEOUT_MILLIS = 3000;
// 等待響應(讀資料)最大逾時
public static int SOCKET_TIMEOUT_MILLIS = 6000;
// 從連接配接池中擷取可用連接配接最大逾時時間
public static int CONNECTION_REQUEST_TIMEOUT_MILLIS = 2000;
// 連接配接池中的最大連接配接數
public static int MAX_CONN_TOTAL =15;
// 連接配接同一個route最大的并發數
public static int MAX_CONN_PER_ROUTE = 10;
private static HttpHost[] HTTP_HOST;
private RestClientBuilder builder;
private RestClient restClient;
private RestHighLevelClient restHighLevelClient;
private static ElasticRestClientFactory restClientFactory = new ElasticRestClientFactory();
private ElasticRestClientFactory(){}
public static ElasticRestClientFactory build(HttpHost[] httpHost, Integer maxConnectNum, Integer maxConnectPerRoute){
HTTP_HOST = httpHost;
MAX_CONN_TOTAL = maxConnectNum;
MAX_CONN_PER_ROUTE = maxConnectPerRoute;
return restClientFactory;
}
public static ElasticRestClientFactory build(HttpHost[] httpHost,Integer connectTimeOut, Integer socketTimeOut,
Integer connectionRequestTime,Integer maxConnectNum, Integer maxConnectPerRoute){
HTTP_HOST = httpHost;
CONNECT_TIMEOUT_MILLIS = connectTimeOut;
SOCKET_TIMEOUT_MILLIS = socketTimeOut;
CONNECTION_REQUEST_TIMEOUT_MILLIS = connectionRequestTime;
MAX_CONN_TOTAL = maxConnectNum;
MAX_CONN_PER_ROUTE = maxConnectPerRoute;
return restClientFactory;
}
public void init(){
builder = RestClient.builder(HTTP_HOST);
setConnectTimeOutConfig();
setMutiConnectConfig();
restClient = builder.build();
restHighLevelClient = new RestHighLevelClient(builder);
log.info("Elasticsearch highLevelRestClient init successful");
}
// 配置連接配接延時時間
public void setConnectTimeOutConfig(){
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(CONNECT_TIMEOUT_MILLIS);
requestConfigBuilder.setSocketTimeout(SOCKET_TIMEOUT_MILLIS);
requestConfigBuilder.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT_MILLIS);
return requestConfigBuilder;
});
}
// 使用異步httpclient時設定并發連接配接數
public void setMutiConnectConfig(){
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(MAX_CONN_TOTAL);
httpClientBuilder.setMaxConnPerRoute(MAX_CONN_PER_ROUTE);
return httpClientBuilder;
});
}
public RestClient getClient(){
return restClient;
}
public RestHighLevelClient getRestHighClient(){
return restHighLevelClient;
}
public void close() {
if (restClient != null) {
try {
restClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
log.info("Elasticsearch highLevelRestClient closed");
}
}
3、建立QueryResult查詢結果封裝類
public class QueryResult {
private boolean succesful;
private long took;
private boolean timedout;
private long hitsTotal;
private float maxScore;
private Map<String,Integer> shardsInfo;
private List<Map<String,Object>> hitsBody;
public QueryResult() {
}
public QueryResult(boolean succesful) {
this.succesful = succesful;
}
public boolean getSuccesful() {
return succesful;
}
public void setSuccesful(boolean succesful) {
this.succesful = succesful;
}
public long getTook() {
return took;
}
public void setTook(long took) {
this.took = took;
}
public boolean isTimedout() {
return timedout;
}
public void setTimedout(boolean timedout) {
this.timedout = timedout;
}
public long getHitsTotal() {
return hitsTotal;
}
public void setHitsTotal(long hitsTotal) {
this.hitsTotal = hitsTotal;
}
public float getMaxScore() {
return maxScore;
}
public void setMaxScore(float maxScore) {
this.maxScore = maxScore;
}
public Map<String, Integer> getShardsInfo() {
return shardsInfo;
}
public void setShardsInfo(Map<String, Integer> shardsInfo) {
this.shardsInfo = shardsInfo;
}
public List<Map<String, Object>> getHitsBody() {
return hitsBody;
}
public void setHitsBody(List<Map<String, Object>> hitsBody) {
this.hitsBody = hitsBody;
}
}
4、建立ElasticQueryDSLTemplates模闆類【基于Query DSL】後續會增加基于SQL一套模闆方法
@Component
public class ElasticQueryDSLTemplates {
private static Logger log = LoggerFactory.getLogger(ElasticQueryDSLTemplates.class);
@Autowired
private RestHighLevelClient restHighLevelClient;
public boolean createIndex(String indexName, Builder builder) throws IOException {
Assert.notNull(indexName, "索引名稱不能為空");
CreateIndexRequest request = new CreateIndexRequest(indexName);
request.settings(Settings.builder()
.put("index.number_of_shards", 3) // 分片
.put("index.number_of_replicas", 1) //副本
.put("refresh_interval", "10s")
);
// 建立fullText屬性
Map<String, Object> fullText = new HashMap<>();
fullText.put("type", "text");
fullText.put("analyzer", "ik_max_word"); // 可選ik_max_word、ik_smart
fullText.put("search_analyzer", "ik_smart"); // 可選ik_max_word、ik_smart
fullText.put("term_vector", "with_positions_offsets"); // 全文檢索fvh設定
// 建立fondCode屬性
Map<String, Object> fondCode = new HashMap<>();
fondCode.put("type", "keyword");
Map<String, Object> properties = new HashMap<>();
properties.put("fullText", fullText);
properties.put("fondCode", fondCode);
Map<String, Object> mapping = new HashMap<>();
mapping.put("properties", properties);
request.mapping(mapping);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
return acknowledged;
}
public boolean deleteIndex(String indexName) throws IOException {
Assert.notNull(indexName, "索引名稱不能為空");
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
AcknowledgedResponse deleteIndexResponse = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
return deleteIndexResponse.isAcknowledged();
}
public boolean existsIndex(String indexName) throws IOException {
Assert.notNull(indexName, "索引名稱不能為空");
GetIndexRequest request = new GetIndexRequest(indexName);
return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
}
public List<AnalyzeResponse.AnalyzeToken> analyzeText(String analyzer, String analyzeText) throws IOException {
Assert.notNull(analyzer, "分析器不能為空");
Assert.notNull(analyzeText, "分析文本不能為空");
AnalyzeRequest analyzeRequest = new AnalyzeRequest();
analyzeRequest.analyzer(analyzer);
analyzeRequest.text(analyzeText);
AnalyzeResponse response = restHighLevelClient.indices().analyze(analyzeRequest, RequestOptions.DEFAULT);
return response.getTokens();
}
public boolean addDocument(String indexName, String id, Map<String, Object> docMap) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(id, "索引文檔ID不能為空");
Assert.notNull(docMap, "索引文檔docMap不能為空");
IndexRequest indexRequest = new IndexRequest(indexName).id(id).source(docMap);
indexRequest.opType(DocWriteRequest.OpType.CREATE);
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("添加索引文檔失敗異常。索引名稱【{}】,索引文檔ID【{}】", indexName, id, e);
optFlag = Boolean.FALSE;
}
return optFlag;
}
public Map<String, Object> getDocument(String indexName, String id) {
Map<String, Object> docMap = null;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(id, "索引文檔ID不能為空");
GetRequest request = new GetRequest(indexName, id);
GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
docMap = response.getSourceAsMap();
} catch (Exception e) {
log.error("根據ID擷取索引文檔異常。索引名稱【{}】,索引文檔ID【{}】", indexName, id, e);
}
return docMap;
}
public boolean existsDocument(String indexName, String id) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(id, "索引文檔ID不能為空");
GetRequest request = new GetRequest(indexName, id);
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none_");
optFlag = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("根據ID判斷索引文檔是否存在異常。索引名稱【{}】,索引文檔ID【{}】", indexName, id, e);
}
return optFlag;
}
public boolean deleteDocument(String indexName, String id) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(id, "索引文檔ID不能為空");
GetRequest request = new GetRequest(indexName, id);
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none_");
optFlag = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("根據ID删除索引文檔異常。索引名稱【{}】,索引文檔ID【{}】", indexName, id, e);
}
return optFlag;
}
public boolean updateDocument(String indexName, String id, Map<String, Object> docMap) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(id, "索引文檔ID不能為空");
Assert.notNull(docMap, "索引文檔docMap不能為空");
UpdateRequest request = new UpdateRequest(indexName, id).doc(docMap);
restHighLevelClient.update(request, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("根據ID修改索引文檔異常。索引名稱【{}】,索引文檔ID【{}】", indexName, id, e);
}
return optFlag;
}
public boolean bulkAddDocument(String indexName, List<Map<String, Object>> docMaps) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(docMaps, "索引文檔docMaps不能為空");
BulkRequest bulkRequest = new BulkRequest();
for (int i = 0; i < docMaps.size(); i++) {
Map<String, Object> docMap = docMaps.get(i);
bulkRequest.add(new IndexRequest(indexName).id(docMap.get("id")+"").source(docMaps).opType(DocWriteRequest.OpType.CREATE));
}
restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("批量添加索引文檔異常。索引名稱【{}】", indexName, e);
}
return optFlag;
}
public boolean bulkUpdateDocument(String indexName, List<Map<String, Object>> docMaps) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(docMaps, "索引文檔docMaps不能為空");
BulkRequest bulkRequest = new BulkRequest();
for (int i = 0; i < docMaps.size(); i++) {
Map<String, Object> docMap = docMaps.get(i);
bulkRequest.add(new UpdateRequest(indexName, docMap.get("id")+"").doc(docMap));
}
restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("批量修改索引文檔異常。索引名稱【{}】", indexName, e);
}
return optFlag;
}
public boolean bulkDeleteDocument(String indexName, List<Map<String, Object>> docMaps) {
boolean optFlag = Boolean.TRUE;
try {
Assert.notNull(indexName, "索引名稱不能為空");
Assert.notNull(docMaps, "索引文檔docMaps不能為空");
BulkRequest bulkRequest = new BulkRequest();
for (int i = 0; i < docMaps.size(); i++) {
Map<String, Object> docMap = docMaps.get(i);
bulkRequest.add(new DeleteRequest(indexName, docMap.get("id")+""));
}
restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("批量修改索引文檔異常。索引名稱【{}】", indexName, e);
}
return optFlag;
}
public QueryResult searchForTermsQuery(String indexName, String fieldName, Object... terms ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "精準查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termsQuery(fieldName, terms));
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("精準比對檢索異常。索引名稱【{}】, terms查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForTermsQuery(String indexName, String fieldName, int offset, int pageSize, Object... terms ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "精準查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termsQuery(fieldName, terms));
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("精準比對分頁檢索異常。索引名稱【{}】, terms查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForRangeQuery(String indexName, String fieldName, Map<String, Object> terms, String format) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定range查詢條件
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(fieldName);
for (String key: terms.keySet()) {
switch (key) {
case "gte":
rangeQueryBuilder.gte(terms.get(key));
continue;
case "gt":
rangeQueryBuilder.gt(terms.get(key));
continue;
case "lte":
rangeQueryBuilder.lte(terms.get(key));
continue;
case "lt":
rangeQueryBuilder.lt(terms.get(key));
continue;
default:
break;
}
}
// 設定轉換規則 一般針對時間屬性 dd/MM/yyyy||yyyy
if(StringUtils.isNotEmpty(format)) {
rangeQueryBuilder.format(format);
}
sourceBuilder.query(rangeQueryBuilder);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("單屬性範圍比對檢索異常。索引名稱【{}】, range查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForRangeQuery(String indexName, String fieldName, int offset, int pageSize, Map<String, Object> terms, String format) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定range查詢條件
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(fieldName);
for (String key: terms.keySet()) {
switch (key) {
case "gte":
rangeQueryBuilder.gte(terms.get(key));
continue;
case "gt":
rangeQueryBuilder.gt(terms.get(key));
continue;
case "lte":
rangeQueryBuilder.lte(terms.get(key));
continue;
case "lt":
rangeQueryBuilder.lt(terms.get(key));
continue;
default:
break;
}
}
// 設定轉換規則 一般針對時間屬性 dd/MM/yyyy||yyyy
if(StringUtils.isNotEmpty(format)) {
rangeQueryBuilder.format(format);
}
sourceBuilder.query(rangeQueryBuilder);
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("單屬性範圍比對分頁檢索異常。索引名稱【{}】, range查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForPrefixQuery(String indexName, String fieldName, String term) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "字首模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.prefixQuery(fieldName, term));
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error(" 字首模糊比對檢索異常。索引名稱【{}】, terms查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForPrefixQuery(String indexName, String fieldName, int offset, int pageSize, String term ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "字首模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.prefixQuery(fieldName, term));
//設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error(" 字首模糊比對分頁檢索異常。索引名稱【{}】, terms查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForWildcardQuery(String indexName, String fieldName, String term) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "通配符模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.wildcardQuery(fieldName, term));
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error(" 通配符模糊比對檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForWildcardQuery(String indexName, String fieldName, int offset, int pageSize, String term ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "通配符模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.wildcardQuery(fieldName, term));
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error(" 通配符模糊比對檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForFuzzyQuery(String indexName, String fieldName, Object term) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery(fieldName, term));
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error(" 模糊比對檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForFuzzyQuery(String indexName, String fieldName, int offset, int pageSize, Object term ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(term, "模糊檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery(fieldName, term));
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("模糊比對檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, term, e);
}
return qr;
}
public QueryResult searchForIdsQuery(String indexName, String fieldName, String... terms ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "ids檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.idsQuery(terms));
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("根據ids比對檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForIdsQuery(String indexName, String fieldName, int offset, int pageSize, String... terms ) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
Assert.notNull(terms, "ids檢索條件term不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.idsQuery(terms));
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("根據ids比對分頁檢索異常。索引名稱【{}】, term查詢字段【{}】,查詢條件【{}】", indexName, fieldName, JSONObject.toJSONString(terms), e);
}
return qr;
}
public QueryResult searchForBoolQuery(String indexName, Map<String, List<QueryBuilder>> terms) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
//Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
//Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定複合查詢
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String key: terms.keySet()) {
switch (key) {
case "must":
List<QueryBuilder> mustQbs = terms.get(key);
for(QueryBuilder qb: mustQbs) {
boolQueryBuilder.must(qb);
}
continue;
case "filter":
List<QueryBuilder> filterQbs = terms.get(key);
for(QueryBuilder qb: filterQbs) {
boolQueryBuilder.filter(qb);
}
continue;
case "mustNot":
List<QueryBuilder> mustNotQbs = terms.get(key);
for(QueryBuilder qb: mustNotQbs) {
boolQueryBuilder.mustNot(qb);
}
continue;
case "should":
List<QueryBuilder> shouldQbs = terms.get(key);
for(QueryBuilder qb: shouldQbs) {
boolQueryBuilder.should(qb);
}
continue;
default:
break;
}
}
sourceBuilder.query(boolQueryBuilder);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("複合比對檢索異常。索引名稱【{}】", indexName, e);
}
return qr;
}
public QueryResult searchForBoolQuery(String indexName, int offset, int pageSize, Map<String, List<QueryBuilder>> terms) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
//Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
//Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定複合查詢
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String key: terms.keySet()) {
switch (key) {
case "must":
List<QueryBuilder> mustQbs = terms.get(key);
for(QueryBuilder qb: mustQbs) {
boolQueryBuilder.must(qb);
}
continue;
case "filter":
List<QueryBuilder> filterQbs = terms.get(key);
for(QueryBuilder qb: filterQbs) {
boolQueryBuilder.filter(qb);
}
continue;
case "mustNot":
List<QueryBuilder> mustNotQbs = terms.get(key);
for(QueryBuilder qb: mustNotQbs) {
boolQueryBuilder.mustNot(qb);
}
continue;
case "should":
List<QueryBuilder> shouldQbs = terms.get(key);
for(QueryBuilder qb: shouldQbs) {
boolQueryBuilder.should(qb);
}
continue;
default:
break;
}
}
sourceBuilder.query(boolQueryBuilder);
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("複合比對分頁檢索異常。索引名稱【{}】", indexName, e);
}
return qr;
}
public QueryResult searchForHighlightBoolQuery(String indexName, Map<String, List<QueryBuilder>> terms) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
//Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
//Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定複合查詢
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String key: terms.keySet()) {
switch (key) {
case "must":
List<QueryBuilder> mustQbs = terms.get(key);
for(QueryBuilder qb: mustQbs) {
boolQueryBuilder.must(qb);
}
continue;
case "filter":
List<QueryBuilder> filterQbs = terms.get(key);
for(QueryBuilder qb: filterQbs) {
boolQueryBuilder.filter(qb);
}
continue;
case "mustNot":
List<QueryBuilder> mustNotQbs = terms.get(key);
for(QueryBuilder qb: mustNotQbs) {
boolQueryBuilder.mustNot(qb);
}
continue;
case "should":
List<QueryBuilder> shouldQbs = terms.get(key);
for(QueryBuilder qb: shouldQbs) {
boolQueryBuilder.should(qb);
}
continue;
default:
break;
}
}
sourceBuilder.query(boolQueryBuilder);
// 高亮構造器
HighlightBuilder highlightBuilder = new HighlightBuilder();
// 全局設定
highlightBuilder.numOfFragments(1);
highlightBuilder.fragmentSize(900);
// 自定義高亮标簽
highlightBuilder.preTags("<em class='searcHighlight'>");
highlightBuilder.postTags("</em>");
HighlightBuilder.Field highlightFullText =new HighlightBuilder.Field("fullText");
// 設定顯示器。支援unified、plain、fvh。預設unified
highlightFullText.highlighterType("fvh");
// 設定片段長度,預設100
highlightFullText.fragmentOffset(300);
// 設定傳回的片段數, 預設5
highlightFullText.numOfFragments(10);
highlightBuilder.field(highlightFullText);
// 添加更多高亮字段
//HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("ip_addr");
//highlightBuilder.field(highlightUser);
// 設定高亮構造器
sourceBuilder.highlighter(highlightBuilder);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("複合比對高亮檢索異常。索引名稱【{}】", indexName, e);
}
return qr;
}
public QueryResult searchForHighlightBoolQuery(String indexName, int offset, int pageSize, Map<String, List<QueryBuilder>> terms) {
QueryResult qr = new QueryResult(Boolean.TRUE);
try {
Assert.notNull(indexName, "索引名稱indexName不能為空");
//Assert.notNull(fieldName, "查詢目标屬性fieldName不能為空");
//Assert.notNull(terms, "範圍查詢條件terms不能為空");
SearchRequest searchRequest = new SearchRequest();
// 設定要查詢的索引名稱
searchRequest.indices(indexName);
// 構造查詢器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設定複合查詢
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String key: terms.keySet()) {
switch (key) {
case "must":
List<QueryBuilder> mustQbs = terms.get(key);
for(QueryBuilder qb: mustQbs) {
boolQueryBuilder.must(qb);
}
continue;
case "filter":
List<QueryBuilder> filterQbs = terms.get(key);
for(QueryBuilder qb: filterQbs) {
boolQueryBuilder.filter(qb);
}
continue;
case "mustNot":
List<QueryBuilder> mustNotQbs = terms.get(key);
for(QueryBuilder qb: mustNotQbs) {
boolQueryBuilder.mustNot(qb);
}
continue;
case "should":
List<QueryBuilder> shouldQbs = terms.get(key);
for(QueryBuilder qb: shouldQbs) {
boolQueryBuilder.should(qb);
}
continue;
default:
break;
}
}
sourceBuilder.query(boolQueryBuilder);
// 高亮構造器
HighlightBuilder highlightBuilder = new HighlightBuilder();
// 全局設定
highlightBuilder.numOfFragments(5);
highlightBuilder.fragmentSize(100);
// 自定義高亮标簽
highlightBuilder.preTags("<em class='searcHighlight'>");
highlightBuilder.postTags("</em>");
HighlightBuilder.Field highlightFullText =new HighlightBuilder.Field("fullText");
// 設定顯示器。支援unified、plain、fvh。預設unified
highlightFullText.highlighterType("fvh");
// 設定片段長度,預設100
highlightFullText.fragmentOffset(100);
// 設定傳回的片段數, 預設5
highlightFullText.numOfFragments(5);
highlightBuilder.field(highlightFullText);
// 添加更多高亮字段
//HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("ip_addr");
//highlightBuilder.field(highlightUser);
// 設定高亮構造器
sourceBuilder.highlighter(highlightBuilder);
// 設定分頁
sourceBuilder.from(offset).size(pageSize);
// 執行查詢
excuteQuery(searchRequest, sourceBuilder, qr);
} catch (Exception e) {
log.error("複合比對高亮分頁檢索異常。索引名稱【{}】", indexName, e);
}
return qr;
}
public void excuteQuery(SearchRequest searchRequest, SearchSourceBuilder sourceBuilder, QueryResult qr) throws IOException {
// 設定逾時
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// 按查詢評分降序 排序支援四種:Field-, Score-, GeoDistance-, ScriptSortBuilder
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
// 設定查詢器
searchRequest.source(sourceBuilder);
// 執行查詢
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 封裝查詢結果
doQueryResult(searchResponse, qr);
}
public void doQueryResult(SearchResponse searchResponse, QueryResult qr) {
// 查詢耗時
TimeValue took = searchResponse.getTook();
qr.setTook(took.getMillis());
// 是否逾時
qr.setTimedout(searchResponse.isTimedOut());
// 查詢總數
qr.setHitsTotal(searchResponse.getHits().getTotalHits().value);
// 最高評分
qr.setMaxScore(searchResponse.getHits().getMaxScore());
// 分片資訊
Map<String, Integer> shardsInfo = new HashMap<String, Integer>();
shardsInfo.put("total", searchResponse.getTotalShards());
shardsInfo.put("successful", searchResponse.getSuccessfulShards());
shardsInfo.put("skipped", searchResponse.getSkippedShards());
shardsInfo.put("failed", searchResponse.getFailedShards());
qr.setShardsInfo(shardsInfo);
// 擷取查詢結果
List<Map<String, Object>> hitsBody = new ArrayList<Map<String, Object>>();
SearchHits termhts=searchResponse.getHits();
for(SearchHit hit:termhts){
Map<String, Object> hitMap = hit.getSourceAsMap();
// 高亮内容封裝
if(hitMap!= null) {
Map<String, HighlightField> highMap = hit.getHighlightFields();
Map<String, String> highTextMap = new HashMap<String, String>();
if(highMap != null) {
for (String highKey: highMap.keySet()) {
String fieldName = highMap.get(highKey).getName();
Text highText = (highMap.get(highKey).fragments())[0];
highTextMap.put(fieldName, highText.toString());
}
hitMap.put("highlight", highTextMap);
}
}
hitsBody.add(hitMap);
}
qr.setHitsBody(hitsBody);
}
}