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();
    }
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值