Elasticsearch小結(7.5)Java版

Elasticsearch7.5 經驗分享

1查詢
ES是非關係型數據庫,可將兩張表設置成父子關聯表,查詢一張表可將另一張表的相關信息帶出來,
更多表的查詢只能先查第一張表,遍歷第一次查詢結果,循環裏進行二次、三次...的查詢,後面的查詢用Multi並行多個表的查詢。
分頁展示的話,一次展示幾條,僅僅幾條進行關聯查詢也只是勉強夠用,做Excel批量導出這種功能,是完全不可以的,太慢了。
做分頁展示它總條數默認顯示一萬條,也可以設置顯示真實條數,但當點擊最後一頁時,會報錯,因爲它是遊標計算的,點擊最後一頁遊標要跑到最後,後臺撐不住太大的計算量,最多隻查出幾萬條,一般採用百度的做法,不顯示總頁數,無點擊最後一頁按鈕,而且每次查詢排序可能不一樣,因爲是計算出來的。
聚合查詢(按條件統計)很糟糕(慢)。
2.增、刪、改
ES的增、刪、改功能並不理想,速度比較慢。修改是線程不安全的。不適合做頻繁改動的表。
3.總結
ES做單表查詢是很好的速度非常快。做分頁、關聯、聚合都不合適。

Elasticsearch重要概念

cluster(集羣)

集羣中有多個節點,其中有一個爲主節點,這個主節點是可以通過選舉產生的,主從節點是對於集羣內部來說的。
es是去中心化的,就是無中心節點,從外部來看es集羣,邏輯上是個整體,與任何一個節點的通信和與整個es集羣通信是等價的。

node(節點)

每個運行實例(服務器進程)爲一個節點,每個節點可在同一機器上,也可在不同的機器上。

routing(路由)

找到此文檔的主分片(文檔的位置),默認情況下,這個值是由文檔的id生成。

shards(分片)

es可以把一個完整的索引分成多個分片,把一個大的索引拆分成多個,分佈到不同的節點上。構成分佈式搜索。分片的數量只能在索引創建前指定,並且索引創建後不能更改。

primary shard(主分片)

每個文檔都存儲在一個分片中,當存一個文檔的時候,會先存儲在主分片中,然後複製到副本中。默認一個索引有5個主分片。可在制定分片的數量,當分片一旦建立,分片的數量則不能修改。

replica shard(副本分片)

每一個分片有零個或多個副本。副本主要是主分片的複製,其中有兩個目的:
1、增加高可用性:當主分片失敗的時候,可以從副本分片中選擇一個作爲主分片。
2、提高性能:當查詢的時候可以到主分片或者副本分片中進行查詢。
默認情況下,一個主分配有一個副本,但副本的數量可以在後面動態的配置增加。副本必須部署在不同的節點上,不能部署在和主分片相同的節點上。

template(模板)

索引可使用預定義的模板進行創建,這個模板稱作Index templates。模板設置包括settings和mappings。

index(索引)

索引就是一個擁有相似特徵的文檔的集合。
一個索引由一個名字來標識(必須全部是小寫字母的),對此索引中的文檔進行搜索、更新和刪除的時候,都要用到這個名字。在一個集羣中,你能夠創建任意多個索引。

type(類型)

通常,會爲具有一組相同字段的文檔定義一個類型。一個type下的document,都有相同的field。
一種type就像一類表。如用戶表、員工表等。
注意:
  - ES 5.x中一個index可以有多種type。
  - ES 6.x中一個index只能有一種type。
  - ES 7.x以後,將移除type這個概念。

mapping(映射)

定義每個字段的類型、字段所使用的分詞器等。相當於關係型數據庫中的表結構。一個映射可以事先被定義,或者在第一次存儲文檔的時候自動識別。

document(文檔)

可被索引的基礎信息單元,一個document可以是一條數據,通常用JSON數據結構表示,每個index下的type中,可以去存儲多個document。一個document裏面有多個field。

field(字段)

一個文檔中包含零個或者多個字段,字段可以是一個簡單的值(例如字符串、整數、日期),也可以是一個數組或對象的嵌套結構。字段類似於關係數據庫中的表中的列。

source field(源)

默認情況下,你的原文檔將被存儲在_source這個字段中,當你查詢的時候也是返回這個字段。
這可從搜索結果中訪問原始的對象,這個對象返回一個精確的json字符串,這個對象不顯示索引分析後的其他任何數據。

id

id是一個文件的唯一標識,如果在存庫的時候沒有提供id,系統會自動生成一個id,文檔的index/type/id必須是唯一的。

recovery(恢復)

代表數據恢復或叫數據重新分佈,es在有節點加入或退出時會根據機器的負載對索引分片進行重新分配,掛掉的節點重新啓動時也會進行數據恢復。

River(數據源)

是其它存儲方式(如:數據庫)同步數據到es的一個方法。它是以插件方式存在的一個es服務,通過讀取river中的數據並把它索引到es中。

gateway(持久化)

代表es索引的持久化存儲方式,es默認是先把索引存放到內存中,當內存滿了時再持久化到硬盤。當這個es集羣關閉再重新啓動時就會從gateway中讀取索引數據。
es支持多種類型的gateway,有本地文件系統(默認),分佈式文件系統,Hadoop的HDFS和amazon的s3雲存儲服務。

discovery.zen(找節點)

代表es的自動發現節點機制,es是一個基於p2p的系統,它先通過廣播尋找存在的節點,再通過多播協議來進行節點之間的通信,同時也支持點對點的交互。

Transport(交互)

代表es內部節點或集羣與客戶端的交互方式,默認內部是使用tcp協議進行交互,同時它支持http協議(json格式)、thrift、servlet、memcached、zeroMQ等的傳輸協議(通過插件方式集成)。

term(索引詞)

索引詞,在elasticsearch中索引詞(term)是一個能夠被索引的精確值。foo,Foo Foo幾個單詞是不相同的索引詞。索引詞(term)是可以通過term查詢進行準確的搜索。

text(文本)

是一段普通的非結構化文字,通常,文本會被分析稱一個個的索引詞,存儲在elasticsearch的索引庫中,爲了讓文本能夠進行搜索,
文本字段需要事先進行分析;當對文本中的關鍵詞進行查詢的時候,搜索引擎應該根據搜索條件搜索出原文本。

analysis(分析)

將文本轉換爲索引詞的過程,分析的結果依賴於分詞器,比如: FOO BAR, Foo-Bar, foo bar這幾個單詞有可能會被分析成相同的索引詞foo和bar,這些索引詞存儲在elasticsearch的索引庫中。當用 FoO:bAR進行全文搜索的時候,搜索引擎根據匹配計算也能在索引庫中搜索出之前的內容。這就是elasticsearch的搜索分析。

replica(副本)

shard的replica副本,replica可以在shard故障時提供備用服務。多個replica可提升搜索操作的吞吐量和性能。

segment(分段)

一個shard包含多個segment,每個segment都是倒排索引。查詢時,每個shard會把所有segment結果彙總作爲shard的結果返回。

Elasticsearch官網JavaAPI

SpringBoot的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jackchen</groupId>
    <artifactId>EsDemo4</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <elastic-version>7.5.0</elastic-version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.5.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.elasticsearch.client</groupId>
                    <artifactId>elasticsearch-rest-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.5.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--反射用到-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- java編譯插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>

                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

java客戶端的重要組件

SearchRequest 、SearchSourceBuilder 、QueryBuilder 、SearchResponse 、SearchHit

public static void testRequest()throws Exception{
	// 創建請求對象,設置查詢多個文檔庫,也可指定單個文檔庫。
	SearchRequest request = new SearchRequest("index01","index02","index03");
	// 也可通過 indices 方法指定文檔庫中
	request.indices("posts01","posts02", "posts03");
	// 設置指定查詢的路由分片
	request.routing("routing");
	// 指定優先去某個分片上去查詢(默認的是隨機先去某個分片)
	request.preference("_local");
	// 設置緩存
	request.requestCache();
	// 取出查詢語句
	request.toString();
}

public static void testSource()throws Exception{
	//創建源
	SearchSourceBuilder source= new SearchSourceBuilder();
	// 第幾頁
	source.from(0);
	// 每頁多少條數據(默認是10條)
	source.size(100);
	// 設置排序規則
	source.sort(new ScoreSortBuilder().order(SortOrder.DESC));
	source.sort(new FieldSortBuilder("id").order(SortOrder.ASC));
	//獲取的字段(列)和不需要獲取的列
	String[] includeFields = new String[]{"birthday","name"};
	String[] excludeFields = new String[]{"age","address"};
	source.fetchSource(includeFields,excludeFields);
	// 設置超時時間
	source.timeout(new TimeValue(60, TimeUnit.SECONDS));
	source.highlighter();// 高亮
	source.aggregation(AggregationBuilders.terms("by_company"));// 聚合
	//分詞查詢
	source.profile(true);
	source.query();
}

public static void testBuilder()throws Exception{
	//全匹配(查出全部)
	MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
	//匹配查詢
	MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("","").analyzer("");
	//匹配文本查詢
	MatchPhraseQueryBuilder matchPhraseQuery = QueryBuilders.matchPhraseQuery("","");
	//匹配文本前綴查詢
	MatchPhrasePrefixQueryBuilder matchPhrasePrefixQuery = QueryBuilders.matchPhrasePrefixQuery("","");
	//判斷莫子是否有值(String)
	ExistsQueryBuilder existsQuery = QueryBuilders.existsQuery("");
	//前綴查詢
	PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("","");
	//精確查詢
	TermQueryBuilder termQuery = QueryBuilders.termQuery("","");
	//範圍查詢
	RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("birthday").from("2016-01-01 00:00:00");
	QueryStringQueryBuilder queryBuilder009 = QueryBuilders.queryStringQuery("");
	QueryBuilders.disMaxQuery();

	HighlightBuilder highlightBuilder = new HighlightBuilder();
	HighlightBuilder.Field highlightTitle =
			new HighlightBuilder.Field("title");
	highlightTitle.highlighterType("unified");
	highlightBuilder.field(highlightTitle);
	HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
	highlightBuilder.field(highlightUser);

	// 組合器
	BoolQueryBuilder builder = QueryBuilders.boolQuery();
	//過濾
	builder.filter();
	//且
	builder.must();
	//非
	builder.mustNot();
	//或
	builder.should();
}


public static void testResponse()throws Exception {
	RestHighLevelClient client = new RestHighLevelClient(
			RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
	SearchRequest searchRequest = new SearchRequest("user");
	// 同步
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	RestStatus status = response.status();
	TimeValue took = response.getTook();
	Boolean terminatedEarly = response.isTerminatedEarly();
	boolean timedOut = response.isTimedOut();
	int totalShards = response.getTotalShards();
	int successfulShards = response.getSuccessfulShards();
	int failedShards = response.getFailedShards();
	for (ShardSearchFailure failure : response.getShardFailures()) {
		// failures should be handled here
	}
	// 異步
	ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
		@Override
		public void onResponse(SearchResponse searchResponse) {
		}
		@Override
		public void onFailure(Exception e) {
		}
	};
	client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
}

public static void testHits()throws Exception {
	RestHighLevelClient client = new RestHighLevelClient(
			RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
	SearchRequest searchRequest = new SearchRequest("user");
	// 同步
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

	SearchHits hits = response.getHits();
	TotalHits totalHits = hits.getTotalHits();
	//總數
	long numHits = totalHits.value;
	//
	TotalHits.Relation relation = totalHits.relation;
	float maxScore = hits.getMaxScore();
	SearchHit[] searchHits = hits.getHits();
	for (SearchHit hit : searchHits) {
		String index = hit.getIndex();
		String id = hit.getId();
		float score = hit.getScore();
		String sourceAsString = hit.getSourceAsString();
		Map<String, Object> sourceAsMap = hit.getSourceAsMap();
		String documentTitle = (String) sourceAsMap.get("title");
		List<Object> users = (List<Object>) sourceAsMap.get("user");
		Map<String, Object> innerObject =
				(Map<String, Object>) sourceAsMap.get("innerObject");
	}
	// 高亮獲取
	for (SearchHit hit : response.getHits()) {
		Map<String, HighlightField> highlightFields = hit.getHighlightFields();
		HighlightField highlight = highlightFields.get("title");
		Text[] fragments = highlight.fragments();
		String fragmentString = fragments[0].string();
	}
	// 獲取聚合結果
	Aggregations aggregations = response.getAggregations();
	Terms byCompanyAggregation = aggregations.get("by_company");
	Terms.Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic");
	Avg averageAge = elasticBucket.getAggregations().get("average_age");
	double avg = averageAge.getValue();

	// 獲取大量聚合結果
	Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
	Terms companyAggregation = (Terms) aggregationMap.get("by_company");
	List<Aggregation> aggregationList = aggregations.asList();
	for (Aggregation agg : aggregations) {
		String type = agg.getType();
		   if (type.equals(TermsAggregationBuilder.NAME)) {
			 Terms.Bucket elasticBucket2 = ((Terms) agg).getBucketByKey("Elastic");
			 long numberOfDocs = elasticBucket2.getDocCount();
		   }
		}
}

CountRequest(統計查出數量)(快)

    public static void test001()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
                new HttpHost("127.0.0.1", 9200, "http")));
        //統計匹配數量(不查出表的內容,更快。)
        CountRequest countRequest = new CountRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "小");
        sourceBuilder.query(queryBuilder);
        countRequest.source(sourceBuilder);
        CountResponse response =client.count(countRequest, RequestOptions.DEFAULT);
        long count = response.getCount();
        RestStatus status = response.status();
        Boolean terminatedEarly = response.isTerminatedEarly();
        int totalShards = response.getTotalShards();
        int skippedShards = response.getSkippedShards();
        int successfulShards = response.getSuccessfulShards();
        int failedShards = response.getFailedShards();
        System.out.println("**************************count: "+count);
        System.out.println("status: "+status);
        System.out.println("terminatedEarly: "+terminatedEarly);
        System.out.println("totalShards: "+totalShards);
        System.out.println("skippedShards: "+skippedShards);
        System.out.println("successfulShards: "+successfulShards);
        System.out.println("failedShards: "+failedShards);
        for (ShardSearchFailure failure : response.getShardFailures()) {
            System.out.println("failure: "+failure);
        }
        client.close();
    }

ES的增、刪、改、批量操作

    //單條增
    public static void addDocment()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));

        //Map提供供文檔源
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("name", "小紅");
        jsonMap.put("sex", "女");
        jsonMap.put("age", 22);
        jsonMap.put("birthDay", new Date());
        jsonMap.put("message", "測試");
        IndexRequest indexRequest1 = new IndexRequest("user2", "doc", "5")
                .source(jsonMap);
        // 同步執行
        IndexResponse indexResponse1 =client.index(indexRequest1,RequestOptions.DEFAULT);
        client.close();


        //XContentBuilder提供供文檔源
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.field("name", "South");
            builder.timeField("birthDay", new Date());
            builder.field("message", "第二個小demo");
        }
        builder.endObject();
        IndexRequest indexRequest2 = new IndexRequest("user", "doc", "2")
                .source(builder);
        // 同步執行
        IndexResponse indexResponse2 =client.index(indexRequest2,RequestOptions.DEFAULT);
        String index = indexResponse1.getIndex();
        String type = indexResponse1.getType();
        String id = indexResponse1.getId();
        long version = indexResponse1.getVersion();
        RestStatus restStatus = indexResponse1.status();
        DocWriteResponse.Result result = indexResponse1.getResult();
        ReplicationResponse.ShardInfo shardInfo = indexResponse1.getShardInfo();
        client.close();
    }

    //刪
    public void deleteTest()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
                new HttpHost("127.0.0.1", 9200, "http")));
        DeleteRequest request = new DeleteRequest("posts","1");
        DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
    }

    //單個改
    public static void updateDocment()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("name", "JunSouth");
        UpdateRequest updateRequest = new UpdateRequest("user","doc","6").doc(jsonMap);
        UpdateResponse updateResponse  =client.update(updateRequest,RequestOptions.DEFAULT);
        String index = updateResponse.getIndex();
        String type = updateResponse.getType();
        String id = updateResponse.getId();
        long version = updateResponse.getVersion();
        System.out.println("index:"+index+"  type:"+type+"   id:"+id+"   version:"+version);
        if(updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
            System.out.println("文檔已創建");
        }else if(updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
            System.out.println("文檔已更新");
        }else if(updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
            System.out.println("文檔已刪除");
        }else if(updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
            System.out.println("文檔不受更新的影響");
        }
        client.close();
    }


  //批量操作
    public static void bulkDocment()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.add(new IndexRequest("user","doc","5")
                .source(XContentType.JSON,"name", "test")); // 將第一個 IndexRequest 添加到批量請求中
        bulkRequest.add(new IndexRequest("user","doc","6")
                .source(XContentType.JSON,"name","test")); // 第二個
        BulkResponse bulkResponse = client.bulk(bulkRequest,RequestOptions.DEFAULT);
        boolean falgs = bulkResponse.hasFailures();    // true 表示至少有一個操作失敗
        System.out.println("falgs: "+falgs);
        for (BulkItemResponse bulkItemResponse : bulkResponse) { // 遍歷所有的操作結果
            DocWriteResponse itemResponse = bulkItemResponse.getResponse(); // 獲取操作結果的響應,可以是 IndexResponse,UpdateResponse or DeleteResponse,它們都可以慚怍是 DocWriteResponse 實例。
            if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
                IndexResponse indexResponse = (IndexResponse) itemResponse;
                System.out.println("index 操作後的響應結果");
            }else if(bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
                UpdateResponse updateResponse = (UpdateResponse) itemResponse;
                System.out.println("update 操作後的響應結果");
            }else if(bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {
                DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
                System.out.println("delete 操作後的響應結果");
            }
        }
        for (BulkItemResponse bulkItemResponse : bulkResponse) {
            if (bulkItemResponse.isFailed()) {                                      // 檢測給定的操作是否失敗
                BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
                System.out.println("獲取失敗信息: "+failure);
            }
        }
        client.close();
    }

IndexRequest、DeleteRequest、UpdateRequest、BulkRequest 

IndexRequest indexRequest
設置路由值。
indexRequest.routing("routing");
設置parent值。
indexRequest.parent("parent");
等待主碎片可用的作爲TimeValue的超時。
等待主碎片可用的作爲String的超時。
indexRequest.timeout(TimeValue.timeValueSeconds(1));
indexRequest.timeout("1s");
刷新策略作爲WriteRequest.RefreshPolicy實例提供。
刷新策略作爲String提供。
indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
indexRequest.setRefreshPolicy("wait_for");
設置版本。
indexRequest.version(2);
設置版本類型。
indexRequest.versionType(VersionType.EXTERNAL);
操作類型作爲DocWriteRequest.OpType值提供。
作爲String提供的操作類型:可以爲create或update(默認)。
indexRequest.opType(DocWriteRequest.OpType.CREATE);
indexRequest.opType("create");
索引文檔之前要執行的攝取管道的名稱。
indexRequest.setPipeline("pipeline");
	
	
DeleteRequest deleteRequest
設置路由值。
deleteRequest.routing("routing");
設置parent值。
deleteRequest.parent("parent");
等待主碎片可用的作爲TimeValue的超時。
等待主碎片可用的作爲String的超時。
deleteRequest.timeout(TimeValue.timeValueMinutes(2)); 
deleteRequest.timeout("2m");
將刷新策略作爲WriteRequest.RefreshPolicy實例。
將刷新策略作爲String。
deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
deleteRequest.setRefreshPolicy("wait_for");
設置版本。
deleteRequest.version(2);
設置版本類型。
deleteRequest.versionType(VersionType.EXTERNAL);


UpdateRequest updateRequest
設置超時時間。
updateRequest.timeout(TimeValue.timeValueSeconds(1)); 
updateRequest.timeout("1s"); 
設置刷新策略。
updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); 
updateRequest.setRefreshPolicy("wait_for");  
設置衝突後重試次數。
updateRequest.retryOnConflict(3);
獲取數據源,默認是開啓的。
updateRequest.fetchSource(true); 
包括特定字段。
String[] includes = new String[]{"updated", "r*"};
String[] excludes = Strings.EMPTY_ARRAY;
updateRequest.fetchSource(new FetchSourceContext(true, includes, excludes)); 
排除特定字段。
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"updated"};
updateRequest.fetchSource(new FetchSourceContext(true, includes, excludes)); 
指定版本。
updateRequest.version(2); 
禁用 noop detection
updateRequest.scriptedUpsert(true); 
設置如果更新的文檔不存在,就必須要創建一個。
updateRequest.docAsUpsert(true); 

BulkRequest bulkRequest 
設置超時時間
bulkRequest.timeout(TimeValue.timeValueMinutes(2)); 
request.timeout("2m"); 
設置刷新策略
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); 
bulkRequest.setRefreshPolicy("wait_for"); 
設置在批量操作前必須有幾個分片處於激活狀態。
bulkRequest.waitForActiveShards(2); 
bulkRequest.waitForActiveShards(ActiveShardCount.ALL);      // 全部分片都處於激活狀態
bulkRequest.waitForActiveShards(ActiveShardCount.DEFAULT);  // 默認
bulkRequest.waitForActiveShards(ActiveShardCount.ONE);      // 一個

ES查詢

//查詢某索引下全部數據
public static void searchAll()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("user");  // 設置搜索的 index 。
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder); //設置搜索,可以是任何類型的 QueryBuilder.
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        float maxScore = hits.getMaxScore();
        for (SearchHit hit : hits.getHits()) {
            System.out.println("hit: "+hit);
            String sourceAsString = hit.getSourceAsString();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            System.out.println("name: "+name);
        }
        client.close();

        //匹配查詢器
       QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
                                                .fuzziness(Fuzziness.AUTO)
                                                .prefixLength(3)
                                                .maxExpansions(10);
        searchSourceBuilder.query(matchQueryBuilder);

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("name"); // title 字段高亮
        highlightTitle.highlighterType("unified");  // 配置高亮類型
        highlightBuilder.field(highlightTitle);  // 添加到 builder
        HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
        highlightBuilder.field(highlightUser);
        searchSourceBuilder.highlighter(highlightBuilder);
}


    //普通條件查詢
public static void search01()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("user");  // 設置搜索的 index 。
        // 查詢器
        QueryBuilder queryBuilder01 = QueryBuilders.termQuery("name", "test"); //完全匹配
        QueryBuilder queryBuilder02 =QueryBuilders.fuzzyQuery("name", "t");    //模糊查詢
        QueryBuilder queryBuilder03 =QueryBuilders.prefixQuery("name", "小"); //前綴查詢
        QueryBuilder queryBuilder04 =QueryBuilders.matchQuery("name", "小");    //匹配查詢
        WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery("name","*jack*");//搜索名字中含有jack文檔(name中只要包含jack即可)

        // 搜索器(排序、分頁...)。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder04);   // 設置搜索條件
        searchSourceBuilder.from(0); // 起始 index
        searchSourceBuilder.size(5); // 大小 size
      //  searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // 設置搜索的超時時間
      //  searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); // 根據分數 _score 降序排列 (默認行爲)
      //  searchSourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));  // 根據 id 降序排列
        searchRequest.source(searchSourceBuilder); // 將 SearchSourceBuilder  添加到 SeachRequest 中。
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        float maxScore = hits.getMaxScore();
        for (SearchHit hit : hits.getHits()) {
            String sourceAsString = hit.getSourceAsString();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            System.out.println("hit: "+hit);
            System.out.println("name: "+name);
        }
        client.close();
}


// 聚合查詢
public static void search02()throws Exception{
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("user2");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 根據 sex 字段分組
        TermsAggregationBuilder aggregation = AggregationBuilders.terms("my_sex")
                .field("sex.keyword");
        aggregation.subAggregation(AggregationBuilders.avg("avg_age")
                .field("age")); // age(統計的字段)需是數值型
        aggregation.subAggregation(AggregationBuilders.max("max_age")
                .field("age"));
        aggregation.subAggregation(AggregationBuilders.min("min_age")
                .field("age"));
        searchSourceBuilder.aggregation(aggregation);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        Aggregations aggregations = searchResponse.getAggregations();
        Terms sexTerms = aggregations.get("my_sex");

        //獲取每組的信息
        for (Terms.Bucket bucket : sexTerms.getBuckets()) {
            System.out.println("分組的字段名: " + bucket.getKeyAsString());
            System.out.println("每組數量: " + bucket.getDocCount());
        }
        //求平均
        Terms.Bucket elasticBucket1 = sexTerms.getBucketByKey("女");
        Avg averageAge1 = elasticBucket1.getAggregations().get("avg_age");
        double avg1 = averageAge1.getValue();
        System.out.println("女性平均年齡:"+avg1);
        Terms.Bucket elasticBucket2 = sexTerms.getBucketByKey("男");
        Avg averageAge2 = elasticBucket2.getAggregations().get("avg_age");
        double avg2 = averageAge2.getValue();
        System.out.println("男性平均年齡:"+avg2);
        //求最大最小
        Terms.Bucket elasticBucket3 = sexTerms.getBucketByKey("女");
        Max maxAge3 = elasticBucket3.getAggregations().get("max_age");
        double maxAge = maxAge3.getValue();
        System.out.println("女性最大年齡:"+maxAge);
        Terms.Bucket elasticBucket4 = sexTerms.getBucketByKey("女");
        Min maxAge4 = elasticBucket4.getAggregations().get("min_age");
        double minAge = maxAge4.getValue();
        System.out.println("女性最大年齡:"+minAge);
        client.close();
}

// 多查詢
public static void multiSearch()throws Exception{
	MultiSearchRequest multiSearchRequest = new MultiSearchRequest();  
	// 查兩個張索引
	SearchRequest firstSearchRequest = new SearchRequest("user");   
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	searchSourceBuilder.query(QueryBuilders.matchQuery("name", "大黑"));
	firstSearchRequest.source(searchSourceBuilder);
	multiSearchRequest.add(firstSearchRequest);

	SearchRequest secondSearchRequest = new SearchRequest("car");  
	searchSourceBuilder = new SearchSourceBuilder();
	searchSourceBuilder.query(QueryBuilders.matchQuery("weight", "3T"));
	secondSearchRequest.source(searchSourceBuilder);
	multiSearchRequest.add(secondSearchRequest);
	
	// 取值1
	MultiSearchResponse multiSearchResponse = client.msearch(multiSearchRequest,RequestOptions.DEFAULT);
	MultiSearchResponse.Item firstResponse = multiSearchResponse.getResponses()[0];                                 
	SearchResponse firstSearchResponse = firstResponse.getResponse();        
	for (SearchHit hit : firstSearchResponse.getHits()) {
		Map<String, Object> sourceAsMap = hit.getSourceAsMap();
				String name = (String) sourceAsMap.get("name");
	}

	MultiSearchResponse.Item secondResponse = response.getResponses()[1];  
	SearchResponse secondSearchResponse = secondResponse.getResponse();
	for (SearchHit hit : secondSearchResponse.getHits()) {
		Map<String, Object> sourceAsMap = hit.getSourceAsMap();
		String name = (String) sourceAsMap.get("weight");
	}


	// 取值2
	for (MultiSearchResponse.Item item : multiSearchResponse.getResponses()) {
		SearchResponse response = item.getResponse();
			for (SearchHit hit : response.getHits()) {
			String index=hit.getIndex();
			//根據不同索引名作不同的處理。
			if(index.equals("user")){
				Map<String, Object> sourceAsMap = hit.getSourceAsMap();
				String name = (String) sourceAsMap.get("name");
			}else if(index.equals("car")){
				Map<String, Object> sourceAsMap = hit.getSourceAsMap();
				String name = (String) sourceAsMap.get("weight");
			}
		}
	}


    //滾動查詢
 public static void scrollSerach()throws Exception{
        System.out.print("11111111111111111");
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest("user");  // 設置搜索的 index 。
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder); //設置搜索,可以是任何類型的 QueryBuilder.
        //設置每次查詢數量
        searchSourceBuilder.size(3);
        //設置滾動等待時間
        final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1));
        searchRequest.scroll(scroll);
        searchRequest.source(searchSourceBuilder);

        //第一次獲取查詢結果
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        String scrollId = searchResponse.getScrollId();
        SearchHit[] searchHits = searchResponse.getHits().getHits();

        for (SearchHit hit : searchHits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.print("第一次獲取查詢結果,此處可做一些操作。");
            String name = (String) sourceAsMap.get("name");
            System.out.println("name: "+name);
        }
        //遍歷剩餘結果
        while (searchHits != null && searchHits.length > 0) {
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(scroll);
            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            scrollId = searchResponse.getScrollId();
            searchHits = searchResponse.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                System.out.print("遍歷剩餘結果,此處可做一些操作。");
                String name = (String) sourceAsMap.get("name");
                System.out.println("name: "+name);
            }
        }

        // 清除遊標
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
        boolean succeeded = clearScrollResponse.isSucceeded();
        client.close();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章