ElasticSearch5.6.8(四)数据操作 - 增删查改(JAVA API - TransportClient)

使用JAVA来操作Elasticsearch,我的环境为
jdk1.8
ES5.6.8
transport 5.6.8

环境准备

开发需要的jar包

使用maven管理jar包,如果没有安装x-pack插件,只引入上第一个依赖就够

 <!-- ealsticsearch -->
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>transport</artifactId>
      <version>5.6.8</version>
    </dependency>
    <!-- 安装x-pack插件后 -->
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>x-pack-transport</artifactId>
      <version>5.6.8</version>
    </dependency>

JAVA API

创建一个连接

使用封装的方式写一个工具类用于获取操作客户端,类似于jdbc中先写一个获取connection的方法。

无x-pack方式

/**
    * 获取操作连接
    * @return
    */
   public static TransportClient getTransportClient() {

       // 集群设置
       Settings settings = Settings.builder()
               .put("cluster.name", "elasticsearch")//集群名称
               .build();
       TransportClient client = new PreBuiltTransportClient(settings);
       //添加集群地址和tcp服务端口 IP是由集群的各个node的ip组成的数组
       try {
           for (String ip : IP) {
               client.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(ip), 9300)); 
           }
       } catch (UnknownHostException e) {
           e.printStackTrace();
       }
       return client;
   }

安装了x-pack后

这里在贴一下安装了x-pack后使用的初始化方法

public static TransportClient getTransportClient() {
     //安装x-pack后的初始化方法
     Settings settings = Settings.builder()
             .put("cluster.name", clusterName) //集群名
             .put("client.transport.sniff", true) 
             .put("xpack.security.transport.ssl.enabled", false)
             .put("xpack.security.user", "elastic:changme")//x-pack用户密码
             .build();
      //使用的实现类与前面不同     
     TransportClient client = new PreBuiltXPackTransportClient(settings);
     // 一定要注意,9300为elasticsearch的tcp端口
        try {
            for (String ip : IP) {
                client.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(ip), PORT));
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return client;
    }

增加索引和文档数据

创建索引的映射

使用JAVA API创建一个带映射的索引,以通过它的field方法类设置

    TransportClient transportClient = getTransportClient(); 
    CreateIndexRequestBuilder createIndex=transportClient.admin().indices().prepareCreate(index);
        XContentBuilder mapping = XContentFactory.jsonBuilder()
                .startObject()
                .startObject("properties") //设置之定义字段
                .startObject("name").field("type","text").field("analyzed","standard").endObject() //设置分析器
                .startObject("age").field("type","long").endObject()
                .startObject("class_name").field("type","keyword").endObject()
                .startObject("birth").field("type","date").field("format","yyyy-MM-dd").endObject()//设置Date的格式
                .endObject()
                .endObject();
        createIndex.addMapping(type, mapping);
        CreateIndexResponse res=createIndex.execute().actionGet();

插入文档

构建一个request,它有很多类型,创建索引使用IndexRequestBuilder 。
可以不设置id,es可以自动生成_id.
source的类型有很多,可以使用XContentFactory创建XContentBuilder,也可以使用json格式的字符串 ,也可以使用Map来当数据源。

    TransportClient client= ElasticSearchTestConfig.getTransportClient();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("name","张三");
    map.put("age",22);
    IndexRequestBuilder create = clien.prepareIndex("my","text")
                .setSource(map);
    IndexResponse response = create.execute().actionGet();
  TransportClient client = ElasticSearchTestConfig.getTransportClient();
        IndexRequestBuilder create = clien.prepareIndex("my","text")
                .setSource(("{\"name\":\"张三\",\"age\":21 }",XContentType.JSON);
        IndexResponse response = create.execute().actionGet();

批量插入数据

使用BulkRequestBuilder 完成批量插入,虽然能完成批量操作,但一次也不要添加太多。因为request的大小有限制,具体的量与需要插入的数据大小有关。

BulkRequestBuilder bulkRequest = transportClient.prepareBulk();
for(Map source:sources){
   //添加请求
   bulkRequest.add(transportClient.prepareIndex(index,type)
           .setSource(source));
   }
  BulkResponse bulkResponse = bulkRequest.execute().actionGet();
}

删除索引和文档数据

删除索引

删除创建的是DeleteIndexRequestBuilder

//先判断下索引是否存在
 IndicesExistsRequest inExistsRequest = new IndicesExistsRequest(index);
 IndicesExistsResponse inExistsResponse = client.admin().indices()
                .exists(inExistsRequest).actionGet();
  //存在即进行删除操作
 if(inExistsResponse.isExists()){
      DeleteIndexRequestBuilder delete = client.admin().indices().prepareDelete(index);
      DeleteIndexResponse dResponse = delete.execute().actionGet();   
 }

根据id删除数据

DeleteRequestBuilder delete = client.prepareDelete("my","text","1");
        DeleteResponse response = delete.execute().actionGet();

根据搜索返回值删除数据

其中Query是一种QueryBuilder

DeleteByQueryAction.INSTANCE.newRequestBuilder(client).filter(Query).execute();

查看数据、聚合数据、高亮结果

搜索Query

一个搜索使用下面的方式构建使用。面对不同的需求使用不同的QueryBuilder。

 TransportClient client = ElasticSearchTestConfig.getTransportClient();
 //构建一个query 即查询条件
 QueryBuilder match = QueryBuilders.matchQuery("field","text");
 //根据查询条件构建一个查询问句
 SearchRequestBuilder search = client.prepareSearch("index")
                .setQuery(match)
                .setTypes("typeName")  //指定类型 可选
                .setFrom(0).setSize(10) //分页 可选
                .addSort("title", SortOrder.DESC);//排序 可选
 //搜索返回搜索结果
 SearchResponse response = search.get(); 
 //命中的文档 
 SearchHits hits = response.getHits();
 //命中总数
 Long total = hits.getTotalHits()
 //循环查看命中值
 for(SearchHit hit:hits.getHits()){
     //文档元数据
      String index = hit.getIndex();
      //文档的_source的值
      Map<String, Object> sourceMap = hit.getSourceAsMap();
 }      

搜索全部

QueryBuilder matchAll = QueryBuilders.matchAllQuery();

字段值包含搜索

QueryBuilder match = QueryBuilders.matchQuery("field","text");

字段值精确值匹配

QueryBuilder term = QueryBuilders.termQuery("field","text");
QueryBuilder terms = QueryBuilders.termsQuery("field","text","text2","text3");

前缀搜索

QueryBuilder prefix= QueryBuilders.prefixQuery("field","text");

模糊值搜索

FuzzyQueryBuilder fuzzy= QueryBuilders.fuzzyQuery(field, value);

通配符搜索

QueryBuilder wildcard= QueryBuilders.wildcardQuery(field,patten);

搜索语句搜索

QueryBuilder queryString= QueryBuilders.queryStringQuery("queryString");

多条件搜索

搜索需求:
重要性比较高:标题包含Elasticsearch或JAVA
内容同时包含Elasticsearch和JAVA

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.should(QueryBuilders.matchQuery("main_body","Elasticsearch JAVA")
                       .operator(Operator.AND).boost(1))
         .should(QueryBuilders.matchQuery("title","Elasticsearch JAVA"))
                        .operator(Operator.OR).boost(10)
               );

聚合搜索Aggregation

聚合相当于SQL中的group,使用不同的AggregationBuilder能完成不同的聚合操作,这里列举几种聚合。
语法如下:

TransportClient client = ElasticSearchTestConfig.getTransportClient();
//需要给聚合内容一个别名
AggregationBuilder aggregation = AggregationBuilders
    .terms("alias").field("field");
QueryBuilder allQuery = QueryBuilders.matchAllQuery();
SearchResponse response = client.prepareSearch("index")
     .setQuery(allQuery).addAggregation(aggregation).get();
//根据别名获取聚合对象,不同聚合会返回不同的聚合对象
Terms terms = response.getAggregations().get("alias");
for(Terms.Bucket entry:terms.getBuckets()){
    //聚合的属性值
    String value = entry.getKey().toString();
    //聚合后的数量
    long count = entry.getDocCount();
}

聚合某字段

AggregationBuilder aggregation = AggregationBuilders
    .terms("alias").field("field");

统计某字段的总数

ValueCountBuilder vcb=  AggregationBuilders.count("alias").field("field");

去重统计某字段的总数

CardinalityBuilder aggregation = AggregationBuilders.cardinality("alias").field("field");  

聚合时间

可选择不同的时间聚合方式

AggregationBuilder aggregation = AggregationBuilders
    .dateHistogram(alias).field(field)
    .format("yyyy-MM-dd")
    .dateHistogramInterval(DateHistogramInterval.DAY);

搜索高亮

搜索结果高亮显示,使用方法如下

TransportClient client = ElasticSearchTestConfig.getTransportClient();
QueryBuilder query = QueryBuilders.matchQuery("title","JAVA");

//创建高亮配置
HighlightBuilder hiBuilder=new HighlightBuilder();
//配置高亮作用字段
hiBuilder.field("title");
//可以设置返回高亮词周围多少字符,以及返回几个段
hiBuilder.field("main_body",100,1);
//在高亮词前添加标签
hiBuilder.preTags("<em style='color:red'>");
//高亮词的后标签
hiBuilder.postTags("</em>");

SearchResponse response = client.prepareSearch("index")
    .setQuery(query).highlighter(hiBuilder).get();
//循环命中
for(SearchHit hit:response.getHits().getHits()){
      //比如配置了两个字段都高亮,key是字段名,value就是加了高亮的值
      Map<String, HighlightField> highlightFieldMap = hit.getHighlightFields();
      HighlightField highlightField = highlightFieldMap.get("title");
      if(highlightField!=null){
           //获取高亮的所有段
           Text[] fragments = highlightField.getFragments();
           for(Text text:fragments){
                System.out.println("text的值是:"+text);
           }
       }
}

修改已有数据

修改操作使用UpdateRequestBuilder构建一个修改请求,然后使用setDoc方法传入新的值即可,这里采用的不是覆盖而是更新存在值,新增不存在属性的操作

 UpdateResponse response = client.prepareUpdate("my","test","1")
                .setDoc(source).get();

猜你喜欢

转载自blog.csdn.net/g1969119894/article/details/80169055