elasticsearch 複合查詢
ElasticSearch 複合查詢
1.pom依賴
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/transport -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
</dependency><!-- elasticsearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency><!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</dependency>
2.配置
spring:
data:
elasticsearch:
cluster-name: senseguard-logging
cluster-nodes: 172.20.25.89:31191
properties:
client.transport.sniff: true
3.配置類 config
@Configuration
public class EsConfig {
private TransportClient client;@Value("${spring.data.elasticsearch.cluster-name}")
private String clusterName;@Value("${spring.data.elasticsearch.cluster-nodes}")
private String clusterAddress;@Bean
public TransportClient esclient() {
try {
Settings settings = Settings.builder().put("cluster.name", clusterName).build();client = new PreBuiltTransportClient(settings);
String[] nodes = clusterAddress.split(",");
for (String node : nodes) {
if (node.length() > 0) {
String[] hostPort = node.split(":");
this.client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(hostPort[0]),
Integer.parseInt(hostPort[1])));
}
}
} catch (Exception e) {
}
return client;
}}
4. TransportClient 複雜、混合、排序 查詢
/**
* ES巢狀查詢最外層資料轉換成匯出資料.
*
* @param source
* @param export
* @throws ParseException
* @throws ExecutionException
* @throws InterruptedException
*/
public List<DetectHistory> search(ImdaRequest imda)
throws ParseException, InterruptedException, ExecutionException {
List<DetectHistory> detectHistorieList = new LinkedList<>();
try {
// 建立builder
BoolQueryBuilder builder = QueryBuilders.boolQuery();// builder下有must、should以及mustNot 相當於sql中的and、or以及not
Long startTime = imda.getCaptureTimeStart();
Long endTime = imda.getCaptureTimeEnd();// 抓拍時間篩選
builder.must(QueryBuilders.rangeQuery("capturedTime").gte(startTime).lte(endTime));// 攝像頭 ID
if (imda.getCameraIds().size() > 0 && imda.getCameraIds().get(0) > 0) {
builder.must(QueryBuilders.termsQuery("camera.id", imda.getCameraIds()));
}
// 人像庫
if (imda.getFaceDatabase().size() > 0 && imda.getFaceDatabase().get(0) > 0) {
builder.must(QueryBuilders.termsQuery("targetLibrary.id", imda.getFaceDatabase()));
}// 確認時間篩
RangeQueryBuilder confirmRangeQueryBuilder = QueryBuilders.rangeQuery("acknowledge.operationTime");
// 挨個設定查詢條件,沒有就不加,如果是字串型別的,要加keyword字尾
// 確認狀態
if (!StringUtils.isEmpty(imda.getConfirmStatus()) && Integer.parseInt(imda.getConfirmStatus()) > 0) {
if (!StringUtils.isEmpty(imda.getConfirmTimeStart())) {
Long confirmStart = imda.getConfirmTimeStart();
confirmRangeQueryBuilder.gte(confirmStart);
}
if (!StringUtils.isEmpty(imda.getConfirmTimeEnd())) {
Long confirmEnd = imda.getConfirmTimeEnd();
confirmRangeQueryBuilder.lte(confirmEnd);
}
builder.must(confirmRangeQueryBuilder);
builder.must(QueryBuilders.matchPhraseQuery("acknowledge.status.keyword", imda.getConfirmStatus()));
}BoolQueryBuilder keywordQueryShould = QueryBuilders.boolQuery();
String keyword = imda.getName();
// 搜尋關鍵字
if (!StringUtils.isEmpty(keyword)) {
String keywordLower = "*" + keyword.toLowerCase() + "*";
keyword = "*" + keyword + "*";
// 名字
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.lowerName.keyword", keywordLower));
// 部門
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.lowerDept.keyword", keywordLower));
//公司
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.lowerCompany.keyword", keywordLower));
// camera name
keywordQueryShould.should(QueryBuilders.wildcardQuery("camera.name.keyword", keyword));
// keeper-group 名稱
keywordQueryShould.should(QueryBuilders.wildcardQuery("camera.groupName.keyword", keyword));
// 人像庫名稱
keywordQueryShould.should(QueryBuilders.wildcardQuery("targetLibrary.name.keyword", keyword));
// 員工編號
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.cardId.keyword", keyword));
// 單位名稱
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.company.keyword", keyword));
// 國籍
keywordQueryShould.should(QueryBuilders.wildcardQuery("target.nationality.keyword", keyword));
// 確認人的名稱
keywordQueryShould.should(QueryBuilders.wildcardQuery("acknowledge.realname.keyword", keyword));
// 確認人的id
// keywordQueryShould.should(QueryBuilders.wildcardQuery("acknowledge.userId.keyword", keyword));
}builder.must(keywordQueryShould);
// 比對結果
if (!StringUtils.isEmpty(imda.getComparedType()) && imda.getComparedType().size() > 0) {
List<String> types = imda.getComparedType();BoolQueryBuilder comparedBuilder = null;
BoolQueryBuilder comparedShould = QueryBuilders.boolQuery();for (String type : types) {
switch (type) {
case "NORMAL":
comparedBuilder = QueryBuilders.boolQuery();
comparedBuilder.must(QueryBuilders.matchQuery("detectStatus.keyword",
ComparedTypeEnum.NORMAL.getDetectStatus()));
comparedBuilder
.must(QueryBuilders.matchQuery("status.keyword", ComparedTypeEnum.NORMAL.getStatus()));
comparedShould.should(comparedBuilder);
break;
case "ABNORMAL":
comparedBuilder = QueryBuilders.boolQuery();
comparedBuilder.must(QueryBuilders.matchQuery("detectStatus.keyword",
ComparedTypeEnum.ABNORMAL.getDetectStatus()));
comparedBuilder.must(
QueryBuilders.matchQuery("status.keyword", ComparedTypeEnum.ABNORMAL.getStatus()));
comparedShould.should(comparedBuilder);
break;
case "STRANGER":
comparedBuilder = QueryBuilders.boolQuery();
comparedBuilder.must(QueryBuilders.matchQuery("detectStatus.keyword",
ComparedTypeEnum.STRANGER.getDetectStatus()));
comparedBuilder.must(
QueryBuilders.matchQuery("status.keyword", ComparedTypeEnum.STRANGER.getStatus()));
comparedShould.should(comparedBuilder);
break;
}
}builder.must(comparedShould);
}SortBuilder sortBuilder = SortBuilders.fieldSort("capturedTime").order(SortOrder.DESC);
int size = 0;
int from = 0;if (imda.getFrom() == imda.getTo()) {
size = 1;
} else {
size = imda.getTo() - imda.getFrom() + 1;
}
if (imda.getFrom() > SFUUMSConstant.ONE) {
from = imda.getFrom() - 1;
}SearchResponse searchResponse = client.prepareSearch("tdhistory").setTypes("tdhistory")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(builder).addSort(sortBuilder).setFrom(from)
.setSize(size).execute().get();SearchHits searchHits = searchResponse.getHits();
logger.info("td Conditional query total :" + searchHits.getTotalHits());
DetectHistory detectHistory = null;
for (SearchHit searchHit : searchHits) {
detectHistory = JSON.parseObject(searchHit.getSourceAsString(), DetectHistory.class);detectHistorieList.add(detectHistory);
}
return detectHistorieList;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}return detectHistorieList;
}
5.查詢完畢,輸出結果
總結:
1.查詢欄位名要和存的欄位一樣,不然查詢不到結果
2.String 型別的欄位後面要加keyword
3.String 查詢用 QueryStringQueryBuilder,時間段查詢用 RangeQueryBuilder