目錄
?什么是BoolQueryBuilder?
簡(jiǎn)單的復(fù)合查詢
RestHighLevelClient中的matchQuery與matchPhraseQuery與termQuery的在實(shí)際使用中的不同
ES是否能在類型為text的字段的內(nèi)部使用keyword,如果能這樣做的含義是什么?
什么是ES多字段?
ES怎么實(shí)現(xiàn)聚合查詢?
RestHighLevelClient的subAggregation是什么?干什么用的?
什么是RestHighLevelClient的滾動(dòng)查詢?如何實(shí)現(xiàn)?
ES構(gòu)建簡(jiǎn)單搜索
?什么是BoolQueryBuilder?
BoolQueryBuilder是該客戶端庫(kù)中的一個(gè)查詢構(gòu)建器,用于構(gòu)建布爾查詢(bool query)。 布爾查詢是一種復(fù)合查詢,可以將多個(gè)查詢條件組合在一起。
BoolQueryBuilder提供了幾種方法來(lái)構(gòu)建布爾查詢:
1. must(QueryBuilders): 添加一個(gè)“必須匹配”(must)的查詢條件。這意味著文檔必須滿足該查詢條件才能被返回。 相當(dāng)于sql中的and
2. mustNot(QueryBuilders): 添加一個(gè)“不能匹配”(must not)的查詢條件。這意味著文檔不能滿足該查詢條件才能被返回。相當(dāng)于 is not?
3. should(QueryBuilders): 添加一個(gè)“應(yīng)該匹配”(should)的查詢條件。這意味著文檔可以滿足該查詢條件,但不是必須的。 相當(dāng)與or
4. filter(QueryBuilders): 添加一個(gè)“過(guò)濾”(filter)的查詢條件。與must查詢條件類似,但過(guò)濾查詢不會(huì)計(jì)算相關(guān)性得分,通常用于對(duì)結(jié)果進(jìn)行篩選。相當(dāng)與select 的字段
簡(jiǎn)單的復(fù)合查詢
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("field1", "value1"))
.mustNot(QueryBuilders.termQuery("field2", "value2"))
.should(QueryBuilders.termQuery("field3", "value3"))
.filter(QueryBuilders.termQuery("field4", "value4"));
// 將boolQuery用于搜索請(qǐng)求
SearchRequest searchRequest = new SearchRequest("indexName");
searchRequest.source(new SearchSourceBuilder().query(boolQuery));
RestHighLevelClient中的matchQuery與matchPhraseQuery與termQuery的在實(shí)際使用中的不同
1. matchQuery: ?
The matchQuery is a full-text query that analyzes the provided text and generates a query that performs a full-text search on the analyzed text. It is useful when you want to perform a search based on relevance. The matchQuery analyzes the text and generates a set of terms that are used for matching.翻譯:
1.匹配查詢:
matchQuery是一個(gè)全文查詢,用于分析所提供的文本,并生成一個(gè)對(duì)所分析的文本執(zhí)行全文搜索的查詢。當(dāng)您想要根據(jù)相關(guān)性執(zhí)行搜索時(shí),它非常有用。matchQuery分析文本并生成一組用于匹配的術(shù)語(yǔ)。2. matchPhraseQuery:?
The matchPhraseQuery is similar to the matchQuery, but it analyzes the text as a phrase rather than individual terms. It is useful when you want to search for an exact phrase in the text. The matchPhraseQuery considers the order of the terms and their proximity to each other.?2.匹配短語(yǔ)查詢:
matchPhraseQuery類似于matchQuery,但它將文本作為短語(yǔ)而不是單個(gè)術(shù)語(yǔ)進(jìn)行分析。當(dāng)你想在文本中搜索一個(gè)確切的短語(yǔ)時(shí),它很有用。matchPhraseQuery考慮術(shù)語(yǔ)的順序及其彼此之間的接近程度。termQuery: The termQuery is a query that searches for exact terms in a field. It does not analyze the text and is suitable for searching on keyword fields or fields that are not analyzed. The termQuery matches documents that contain an exact term.
術(shù)語(yǔ)查詢:
termQuery是一個(gè)在字段中搜索精確術(shù)語(yǔ)的查詢。它不分析文本,適用于搜索關(guān)鍵字字段或未分析的字段。termQuery匹配包含確切術(shù)語(yǔ)的文檔。總結(jié):
matchQuery和matchPhraseQuery用于全文搜索并考慮相關(guān)性,而termQuery用于精確的術(shù)語(yǔ)匹配,不對(duì)文本執(zhí)行分析。您可以根據(jù)特定的搜索要求選擇適當(dāng)?shù)牟樵冾愋汀?/p>
ok,
所以簡(jiǎn)單的來(lái)說(shuō),
如果搜隨機(jī)的話請(qǐng)使用matchQuery來(lái)完成模糊匹配,
搜索模糊的關(guān)鍵詞使用matchPhraseQuery
對(duì)指定字段進(jìn)行精確的分詞搜索,適用于關(guān)鍵詞精確搜索。
ES是否能在類型為text的字段的內(nèi)部使用keyword,如果能這樣做的含義是什么?
在Elasticsearch中,你可以在類型為"text"的字段內(nèi)部使用"keyword"。
這種使用方式被稱為"multi-fields"(多字段),它允許你在同一個(gè)字段上定義多個(gè)不同類型的子字段。
?當(dāng)你在類型為"text"的字段上同時(shí)定義一個(gè)"keyword"子字段時(shí),它的含義是:
1. "text"類型子字段:該子字段會(huì)對(duì)文本進(jìn)行分析,將其拆分為單個(gè)詞項(xiàng),并應(yīng)用分詞器和過(guò)濾器等分析器組件。這樣可以支持全文搜索和相關(guān)性評(píng)分。
2. "keyword"類型子字段:該子字段會(huì)將整個(gè)文本作為一個(gè)項(xiàng)進(jìn)行索引和搜索,不進(jìn)行分詞和分析。這樣可以實(shí)現(xiàn)精確匹配、排序和聚合操作。
?這種使用方式的好處是,你可以在同一個(gè)字段上同時(shí)支持全文搜索和精確匹配操作,而無(wú)需額外定義多個(gè)字段。例如,你可以使用"text"類型子字段進(jìn)行全文搜索,并使用"keyword"類型子字段進(jìn)行精確匹配或排序。
?以下是一個(gè)示例,展示如何在Elasticsearch中定義一個(gè)包含"text"和"keyword"子字段的字段:
json
{
? "mappings": {
? ? "properties": {
? ? ? "title": {
? ? ? ? "type": "text",
? ? ? ? "fields": {
? ? ? ? ? "keyword": {
? ? ? ? ? ? "type": "keyword"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}
在上面的示例中,"title"字段被定義為"text"類型,并包含一個(gè)名為"keyword"的"keyword"類型子字段。這樣,你可以同時(shí)在"title"字段上進(jìn)行全文搜索和精確匹配操作。
?總而言之,你可以在類型為"text"的字段內(nèi)部使用"keyword"子字段,以實(shí)現(xiàn)同時(shí)支持全文搜索和精確匹配的功能。實(shí)戰(zhàn):
字段
"agent_name": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } },
要求精準(zhǔn)匹配到agent_name為河南神龍公司的所有信息。
// 指定索引 request.indices("smsp_collect_info_new"); // 構(gòu)建查詢條件 SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder(); // 使用精準(zhǔn)分詞 查找 searchSourceBuilder.query(QueryBuilders.termQuery("agent_name.keyword", "河南神龍公司")); //放入文檔中 request.source(searchSourceBuilder); //遠(yuǎn)程查詢 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //獲取結(jié)果 SearchHit[] searchHits = response.getHits().getHits(); for (SearchHit hit : searchHits) { System.out.println(hit.getSourceAsMap().get("agent_name")); }
這里的agent_name字段就是運(yùn)用了多字段的思想/方式。
什么是ES多字段?
ES多字段(Multi-fields)是Elasticsearch中的一個(gè)概念,它允許在一個(gè)字段上定義多個(gè)不同類型的子字段。每個(gè)子字段可以根據(jù)不同的需求進(jìn)行不同的處理和索引,以便在搜索和聚合時(shí)提供更靈活的功能。
?使用多字段的主要目的是在同一個(gè)字段上同時(shí)支持多種查詢需求。例如,你可能想要在一個(gè)字段上進(jìn)行全文搜索、精確匹配和排序等操作。通過(guò)使用多字段,你可以根據(jù)不同的查詢需求定義不同類型的子字段,從而在每個(gè)子字段上使用適當(dāng)?shù)牟樵兎绞健?br> ?多字段可以在映射(mapping)中定義。以下是一個(gè)示例,展示如何在Elasticsearch中定義一個(gè)包含多字段的字段:
json
{
? "mappings": {
? ? "properties": {
? ? ? "title": {
? ? ? ? "type": "text",
? ? ? ? "fields": {
? ? ? ? ? "keyword": {
? ? ? ? ? ? "type": "keyword"
? ? ? ? ? },
? ? ? ? ? "english": {
? ? ? ? ? ? "type": "text",
? ? ? ? ? ? "analyzer": "english"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}
在上面的示例中,"title"字段被定義為"text"類型,并包含兩個(gè)子字段:"keyword"和"english"。其中,"keyword"子字段是"keyword"類型,用于精確匹配和排序,而"english"子字段是"text"類型,并使用英文分析器進(jìn)行全文搜索。
?通過(guò)使用多字段,你可以根據(jù)不同的查詢需求選擇適當(dāng)?shù)淖幼侄芜M(jìn)行搜索、排序和聚合,從而提供更靈活和準(zhǔn)確的搜索體驗(yàn)。
?總而言之,ES多字段是在一個(gè)字段上定義多個(gè)不同類型的子字段,用于在不同的查詢需求下提供靈活的搜索和聚合功能。
ES怎么實(shí)現(xiàn)聚合查詢?
主要是通過(guò)AggregationBuilders來(lái)進(jìn)行聚合條件的構(gòu)建,然后通過(guò)aggregation方法將AggregationBuilders拼接到SearchSourceBuilder 中實(shí)現(xiàn)的。如果有子聚合是通過(guò)subaggregation方法進(jìn)行拼裝的。
聚合查詢的類型
- Range Aggregation:按指定的范圍對(duì)字段進(jìn)行聚合,比如按價(jià)格范圍聚合商品。
- Date Histogram Aggregation:按指定的時(shí)間間隔對(duì)日期字段進(jìn)行聚合,比如按月份聚合銷售數(shù)據(jù)。
- Histogram Aggregation:按指定的數(shù)值間隔對(duì)數(shù)值字段進(jìn)行聚合,比如按價(jià)格區(qū)間聚合商品。
- Terms Aggregation:對(duì)字段進(jìn)行詞條聚合,類似于SQL中的GROUP BY操作。
- Avg Aggregation:計(jì)算字段的平均值。
- Sum Aggregation:計(jì)算字段的總和。
- Max Aggregation:計(jì)算字段的最大值。
- Min Aggregation:計(jì)算字段的最小值。
- Cardinality Aggregation:計(jì)算字段的基數(shù)(不重復(fù)值的數(shù)量)。
查詢+分組聚合實(shí)戰(zhàn)
public void GroupSearch() throws IOException { SearchRequest request = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); request.indices("smsp_collect_info_new"); // 模糊分詞查詢 searchSourceBuilder.query(QueryBuilders.matchQuery("province", "河南")); // 分組聚合查詢 searchSourceBuilder.aggregation(AggregationBuilders .terms("your_agg_name") .field("agent_name.keyword") .subAggregation(AggregationBuilders.count("count_number") // 指定返回的桶的最大數(shù)量為10000 .field("company.keyword")).size(10000)); //放入文檔中 request.source(searchSourceBuilder); //遠(yuǎn)程查詢 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 獲取所有的桶 Terms termsAggregation = response.getAggregations().get("your_agg_name"); for (Terms.Bucket bucket : termsAggregation.getBuckets()) { // 獲得每次聚合的key的值 System.out.println("當(dāng)前的key為:"+bucket.getKeyAsString()); ValueCount countAggregation =bucket.getAggregations().get("count_number"); System.out.println("當(dāng)前鍵下的聚合屬性的總和,"+countAggregation.getValue()); } }
RestHighLevelClient的subAggregation是什么?干什么用的?
RestHighLevelClient的subAggregation是用于在Elasticsearch中進(jìn)行嵌套聚合操作的功能。在Elasticsearch中,聚合是一種用于對(duì)數(shù)據(jù)進(jìn)行分組、過(guò)濾和計(jì)算的功能,可以根據(jù)不同的聚合類型對(duì)字段進(jìn)行統(tǒng)計(jì)、計(jì)算平均值、求和等操作。
subAggregation允許在一個(gè)聚合操作的結(jié)果上進(jìn)行進(jìn)一步的嵌套聚合操作。
通過(guò)使用subAggregation,可以對(duì)聚合結(jié)果進(jìn)行更細(xì)粒度的分析和處理。
例如,可以在terms聚合的結(jié)果上進(jìn)行子聚合,對(duì)每個(gè)聚合桶進(jìn)行更深入的統(tǒng)計(jì)。
以下是一個(gè)使用RestHighLevelClient進(jìn)行subAggregation的示例代碼:
RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"))); SearchRequest searchRequest = new SearchRequest("your_index_name"); // 替換為實(shí)際的索引名 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 添加主聚合 TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("my_terms_agg") .field("your_field_name"); // 替換為實(shí)際的字段名 // 添加子聚合 MaxAggregationBuilder subAggregationBuilder = AggregationBuilders.max("my_max_agg") .field("your_nested_field_name"); // 替換為實(shí)際的嵌套字段名 aggregationBuilder.subAggregation(subAggregationBuilder); searchSourceBuilder.aggregation(aggregationBuilder); searchRequest.source(searchSourceBuilder); try { SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 解析聚合結(jié)果 Terms termsAggregation = searchResponse.getAggregations().get("my_terms_agg"); for (Terms.Bucket bucket : termsAggregation.getBuckets()) { String key = bucket.getKeyAsString(); Max maxAggregation = bucket.getAggregations().get("my_max_agg"); double max = maxAggregation.getValue(); // 處理聚合結(jié)果 System.out.println("Bucket Key: " + key); System.out.println("Max Value: " + max); } } catch (IOException e) { e.printStackTrace(); } client.close();
什么是RestHighLevelClient的滾動(dòng)查詢?如何實(shí)現(xiàn)?
RestHighLevelClient的滾動(dòng)查詢是一種用于在Elasticsearch中檢索大量數(shù)據(jù)的機(jī)制。它允許您通過(guò)多個(gè)請(qǐng)求迭代地獲取結(jié)果集,而不是一次性獲取所有結(jié)果。滾動(dòng)查詢適用于需要處理大量數(shù)據(jù)的情況,例如導(dǎo)出數(shù)據(jù)、數(shù)據(jù)分析等。
?與其他查詢方式相比,滾動(dòng)查詢具有以下優(yōu)勢(shì):
1. 可以處理大量數(shù)據(jù):滾動(dòng)查詢適用于處理超過(guò)單個(gè)請(qǐng)求的結(jié)果集大小限制的情況。它允許您按需獲取數(shù)據(jù),而不會(huì)因?yàn)閿?shù)據(jù)量過(guò)大而導(dǎo)致請(qǐng)求失敗或性能下降。
2. 節(jié)省內(nèi)存:滾動(dòng)查詢通過(guò)每次返回一小批結(jié)果并在服務(wù)器端維護(hù)滾動(dòng)上下文來(lái)減少內(nèi)存消耗。這使得在處理大量數(shù)據(jù)時(shí),不需要將所有結(jié)果加載到內(nèi)存中,從而節(jié)省了內(nèi)存資源。
3. 支持持續(xù)查詢:滾動(dòng)查詢的結(jié)果可以被持續(xù)使用,即使在處理期間索引中的數(shù)據(jù)發(fā)生了變化。您可以使用滾動(dòng)上下文來(lái)保持查詢的一致性,而不受索引更新的影響。
4. 支持并發(fā)處理:通過(guò)使用滾動(dòng)查詢,您可以并發(fā)地處理多個(gè)滾動(dòng)上下文,從而提高查詢的吞吐量和效率。
?需要注意的是,滾動(dòng)查詢也有一些限制和注意事項(xiàng):
1. 滾動(dòng)查詢會(huì)占用服務(wù)器資源:由于滾動(dòng)上下文需要在服務(wù)器端維護(hù),因此會(huì)占用一定的內(nèi)存和計(jì)算資源。在設(shè)計(jì)滾動(dòng)查詢時(shí),需要考慮服務(wù)器的可用資源以及查詢的并發(fā)性能。
2. 滾動(dòng)查詢的結(jié)果可能不是實(shí)時(shí)的:如果在滾動(dòng)查詢期間索引中的數(shù)據(jù)發(fā)生了變化,滾動(dòng)查詢的結(jié)果可能不會(huì)反映最新的數(shù)據(jù)。因此,在滾動(dòng)查詢中處理數(shù)據(jù)時(shí),需要注意數(shù)據(jù)的一致性和實(shí)時(shí)性。
?總之,RestHighLevelClient的滾動(dòng)查詢是一種強(qiáng)大的機(jī)制,可以高效地處理大量數(shù)據(jù)。它提供了靈活的分批獲取結(jié)果的方式,適用于需要處理大數(shù)據(jù)量的場(chǎng)景。實(shí)現(xiàn):
public void ScrollSearch() throws IOException { SearchRequest request = new SearchRequest(); //失效時(shí)間為10min Scroll scroll = new Scroll(TimeValue.timeValueMinutes(10)); //封存快照 request.scroll(scroll); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); request.indices("smsp_collect_info_new"); searchSourceBuilder.query(QueryBuilders.matchQuery("province", "黑龍江")); // 每次查詢2000個(gè),是滾動(dòng)查詢條數(shù)的步長(zhǎng) searchSourceBuilder.size(2000); //放入文檔中 request.source(searchSourceBuilder); //遠(yuǎn)程查詢 SearchResponse response = client.search(request, RequestOptions.DEFAULT); SearchHit[] searchHits = response.getHits().getHits(); //處理第一次的響應(yīng)結(jié)果 for (SearchHit hit : searchHits) { String province = hit.getSourceAsMap().get("province").toString(); System.out.println(province); // 處理每個(gè)查詢結(jié)果 } // 獲取第一次的滾動(dòng)id String scrollId = response.getScrollId(); while (searchHits.length > 0) { // 每循環(huán)一次構(gòu)建一個(gè)新的滾動(dòng)請(qǐng)求。 SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); scrollRequest.scroll(TimeValue.timeValueMinutes(1)); response = client.scroll(scrollRequest, RequestOptions.DEFAULT); // 獲取新的滾動(dòng)請(qǐng)求的滾動(dòng)id scrollId = response.getScrollId(); searchHits = response.getHits().getHits(); // 處理下一批查詢結(jié)果 for (SearchHit hit : searchHits) { String province = hit.getSourceAsMap().get("province").toString(); System.out.println(province); // 處理每個(gè)查詢結(jié)果 } } }
ES構(gòu)建簡(jiǎn)單搜索
使用模糊匹配
public void simpleSearch() throws IOException {
SearchRequest request = new SearchRequest();
// 指定索引
request.indices("smsp_collect_info_new");
// 構(gòu)建查詢條件 查詢某城市
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("city", "鄭州"));
//放入文檔中
request.source(searchSourceBuilder);
//遠(yuǎn)程查詢
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//獲取結(jié)果
SearchHit[] searchHits = response.getHits().getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit.getSourceAsMap().get("city"));
}
}
?使用精準(zhǔn)匹配
// 單條件精準(zhǔn)查詢
public void simpleSearchUseTerm() throws IOException {
SearchRequest request = new SearchRequest();
// 指定索引
request.indices("smsp_collect_info_new");
// 構(gòu)建查詢條件 查詢某城市
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 使用精準(zhǔn)分詞 查找
searchSourceBuilder.query(QueryBuilders.termQuery("agent_name.keyword", "河南神龍公司"));
//放入文檔中
request.source(searchSourceBuilder);
//遠(yuǎn)程查詢
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//獲取結(jié)果
SearchHit[] searchHits = response.getHits().getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit.getSourceAsMap().get("agent_name"));
}
}
如何在實(shí)現(xiàn)mysql中的in查詢+條件查詢
注意關(guān)鍵是QueryBuilders.termsQuery("字段名",list)
小知識(shí):
sourceBuilder.fetchSource(false);設(shè)置后就只返回元數(shù)據(jù),加快速度,減少資源消耗
// in查詢子端口對(duì)應(yīng)的id
public List<String> getIdListBySubPortAndProvince(List<SPA> spaList) {
if (CollectionUtils.isEmpty(spaList)) {
return new ArrayList<>();
}
List<String> subPortList = spaList.stream().map(SPA::getSubPort).collect(Collectors.toList());
List<String> list = new ArrayList<>();
SearchRequest searchRequest = new SearchRequest("smsp_collect_info_new");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 設(shè)置只返回元數(shù)據(jù),加快速度
sourceBuilder.fetchSource(false);
//in查詢
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termsQuery("sub_port", subPortList))
.must(QueryBuilders.termQuery("province.keyword", spaList.get(0).getProvince()));
//
sourceBuilder.query(boolQueryBuilder).size(10000);
searchRequest.source(sourceBuilder);
try {
SearchResponse search = client.
search(searchRequest, RequestOptions.DEFAULT);
log.info("查詢結(jié)果為:{}", search.getHits().getTotalHits());
for (SearchHit hit : search.getHits().getHits()) {
list.add(hit.getId());
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
對(duì)應(yīng)的原始語(yǔ)句
POST /smsp_collect_info_new/_search
{
"bool": {
"must": [
{
"term": {
"sub_port": {
"value": [
"121212121212",
"12121212",
"1212122112122112",
"122121323243434"
],
"boost": 1
}
}
},
{
"term": {
"province.keyword": {
"value": 312132,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
如何實(shí)現(xiàn)批量更新?
大致思路:
1 通過(guò)條件查詢,獲得所有的需要更新的數(shù)據(jù)的id(元數(shù)據(jù)中的id)
大數(shù)據(jù)量的情況使用滾動(dòng)查詢
2 將查詢到的id作為更新的依據(jù)進(jìn)行更新
?
實(shí)現(xiàn):
1 滾動(dòng)查詢獲取id的list
// 滾動(dòng)查詢主端口對(duì)應(yīng)的id
public List<String> SearchIdByMasterPortProvince(String masterPort, String province) {
List<String> idList = new ArrayList<>();
SearchRequest request = new SearchRequest();
//失效時(shí)間為10min
Scroll scroll = new Scroll(TimeValue.timeValueMinutes(10));
//封存快照
request.scroll(scroll);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
request.indices("smsp_collect_info_new");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("master_port", masterPort))
.must(QueryBuilders.termQuery("province.keyword", province));
searchSourceBuilder.query(boolQueryBuilder);
// 每次查詢2000個(gè),是滾動(dòng)查詢條數(shù)的步長(zhǎng)
searchSourceBuilder.size(2000);
searchSourceBuilder.fetchSource(false);
//放入文檔中
request.source(searchSourceBuilder);
//遠(yuǎn)程查詢
SearchResponse response = null;
try {
response = client.search(request, RequestOptions.DEFAULT);
} catch (IOException e) {
throw new RuntimeException(e);
}
SearchHit[] searchHits = response.getHits().getHits();
//處理第一次的響應(yīng)結(jié)果
for (SearchHit hit : searchHits) {
idList.add(hit.getId());
}
// 獲取第一次的滾動(dòng)id
String scrollId = response.getScrollId();
while (searchHits.length > 0) {
// 每循環(huán)一次構(gòu)建一個(gè)新的滾動(dòng)請(qǐng)求。
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
scrollRequest.scroll(TimeValue.timeValueMinutes(1));
try {
response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 獲取新的滾動(dòng)請(qǐng)求的滾動(dòng)id
scrollId = response.getScrollId();
searchHits = response.getHits().getHits();
// 處理下一批查詢結(jié)果
for (SearchHit hit : searchHits) {
idList.add(hit.getId());
// 處理每個(gè)查詢結(jié)果
}
}
return idList;
}
2 更新,傳入idlist文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-722899.html
// 批量更新ES
public void updateEs(List<String> idList, String agentName) {
HashMap<String, Object> hashMap = new HashMap<>();
// 需要更新的字段
hashMap.put("agent_name", agentName);
// 創(chuàng)建批量請(qǐng)求
BulkRequest bulkRequest = new BulkRequest();
int count = 0;
for (String s : idList) {
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index("smsp_collect_info_new")
.id(s)
.doc(hashMap);
bulkRequest.add(updateRequest);
count++;
// 每3000個(gè)提交一次
if (count % 3000 == 0) {
try {
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("ES更新成功,{}", bulk.getItems().length);
} catch (IOException e) {
throw new RuntimeException(e);
}
count = 0;
bulkRequest = new BulkRequest();
}
}
if (count != 0) {
try {
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("ES更新成功,{}", bulk.getItems().length);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
log.info("ES全部更新成功!");
}
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-722899.html
到了這里,關(guān)于精通ES+ES大數(shù)據(jù)查詢常見(jiàn)的疑難雜癥的解決與實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!