网络知识 娱乐 Java操作Elasticsearch的所有方法

Java操作Elasticsearch的所有方法

使用Java操作Elasticsearch的所有方法

13.1 Elasticsearch简介

	Elasticsearch是基于Lucene开发的一个分布式全文检索框架,向Elasticsearch中存储和从Elasticsearch中查询,格式是json。

a)、索引index,相当于数据库中的database。

b)、类型type相当于数据库中的table。

c)、主键id相当于数据库中记录的主键,是唯一的。

d)、文档 document (相当于一条数据)

文档是ElasticSearch的基本单位。在Es中文档以JSON格式来表示

向es中的index下面的type中存储json类型的数据。

e) 、字段是文档中的field 属性,需要对每一个属性定义索引和被搜索的方式

Elasticsearch是RestFul风格的api,通过http的请求形式(注意,参数是url拼接还是请求的json形式哦),发送请求,对Elasticsearch进行操作。查询:get。删除:delete。添加:put/post。修改:put/post。
RESTFul接口url的格式:http://ip:port/index/type/。其中index、type是必须提供的。id是可以选择的,不提供es会自动生成,index、type将信息进行分层,利于管理。

设置setting:

  //如果想要设置Settings
   Settings settings=Settings.builder()
     .put("cluster.name","elasticsearch") //集群名
     .put("client.transport.sniff", true)// 嗅探机制,找到集群
     .put("index.number_of_shards", 2) // 分片数
     .put("index.number_of_replicas", 1) // 副本数
     .build();

13.2 索引、映射、文档CRUD

13.2.1 pom依赖

<dependencies>
        
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>5.4.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

13.2.2 索引

13.2.2.1 创建索引

prepareCreate

/**
 * 创建索引
 */
@Test
public void testCreateIndex() throws UnknownHostException {
    TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY).addTransportAddress(
            new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    //创建索引 blog5
    CreateIndexResponse indexResponse = transportClient.admin().indices() .prepareCreate("blog5").get();//###

    System.out.println(indexResponse.isAcknowledged()); //确认输出:true
    System.out.println(indexResponse.isShardsAcked());//true
    transportClient.close();
}

13.2.2.2 删除索引

两种方法:.prepareDelete( index , type )、delete(new DeleteIndexRequest( index ))

      /**
         * 删除索引
         */
        @Test
        public void testDelIndex() throws Exception {
            //创建Client连接对象
            TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
            
            //删除名称为blog5的索引
            //多数据
            //DeleteIndexResponse deleteIndexResponse = transportClient.admin().indices() .prepareDelete("blog5", "blog").get();//#####
            //对象传参
            DeleteIndexResponse deleteIndexResponse = transportClient.admin().indices().delete(new DeleteIndexRequest("blog5")).get();//#####
            System.out.println(deleteIndexResponse.isAcknowledged());//true
            transportClient.close();
        }

13.2.3 映射 ??

13.2.3.1 创建映射

putMapping

      /**
         * 创建mapping
      */
    @Test
    public void testCreateMapping() throws Exception {
            TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
            //exists方法,判断索引是否存在
            IndicesExistsResponse indicesExistsResponse = transportClient.admin().indices().exists(new IndicesExistsRequest("blog5")).get();
            System.out.println("索引存在:" + indicesExistsResponse.isExists());//索引存在:false
            //判断索引是否存在
            if (!indicesExistsResponse.isExists()) {
                //不存在则创建索引 blog5
                CreateIndexResponse createIndexResponse = transportClient.admin().indices().prepareCreate("blog5").get();
                System.out.println("创建索引:" + createIndexResponse.isAcknowledged());//创建索引:true
            }
            //添加映射
            /**  格式:
             "mappings": {
             "article": {
             "properties": {
             "id": {
             "store": true,
             "type": "long"
             },
             "title": {
             "analyzer": "ik_max_word",
             "store": true,
             "type": "text"
             },
             "content": {
             "analyzer": "ik_max_word",
             "store": true,
             "type": "text"
             }
             }
             } */
            XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                    .startObject()
                    .startObject("article")
                    .startObject("properties")
                    .startObject("id").field("store", true).field("type", "long").endObject()
                    .startObject("title").field("store", true).field("type", "text").field("analyzer", "ik_max_word").endObject()
                    .startObject("content").field("store", true).field("type", "text").field("analyzer", "ik_max_word").endObject()
                    .endObject()
                    .endObject()
                    .endObject();
            //创建映射,映射到索引blog5、类型article上
            PutMappingRequest putMappingRequest = Requests.putMappingRequest("blog5").type("article") .source(xContentBuilder);
    
            PutMappingResponse putMappingResponse = transportClient.admin().indices() .putMapping(putMappingRequest).get();
            System.out.println(putMappingResponse.isAcknowledged());//true
        
            transportClient.close();
    }

13.2.4 文档

13.2.4.1 建立文档

1、XContentBuilder

prepareIndex( index , type , id ).setSource(xContentBuilder)

    @Test
    public void testCreateDocument() throws Exception {
            TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
            //创建文档信息
            XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("id", 1L)
                    .field("title", "ElasticSearch是一个基于Lucene的搜索服务器")
                    .field("content", "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是" + "用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎")
                    .endObject();
            //建立文档对象
            /**
             * 参数一 blog1:表示索引对象
             * 参数二 article:类型
             * 参数三 1:建立id */
            IndexResponse indexResponse = transportClient.prepareIndex("bolg5", "article", "1").setSource(xContentBuilder).get();//###
            System.out.println(indexResponse.status());//CREATED
            transportClient.close();
        } 

2、Jackson

1)Article实体

public class Article {
    private Long id;
    private String title;
    private String content;

    //getter and setter
}

2)代码实现

prepareIndex( index , type , id ).setSource( json )

    @Test
    public void testCreateDocumentByBean() throws Exception {
            TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
    
            //描述json 数据
            //{id:xxx, title:xxx, content:xxx}
            Article article = new Article();
            article.setId(2L);
            article.setTitle("ElasticSearch是一个基于Lucene的搜索服务器22");
            article.setContent("它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口22");
            //转成String类型
            String jsonStr = JSON.toJSON(article).toString();
            //建立文档
            IndexResponse indexResponse = transportClient.prepareIndex("bolg5", "article", String.valueOf(article.getId())).setSource(jsonStr).get();
            System.out.println(indexResponse.status());//CREATED
            transportClient.close();
    }

13.2.4.2 批量建立

     /**
      * 批量添加
     */
    @Test
    public void addDocBatch() throws Exception {
           TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
    
            for (int i = 0; i < 100; i++) {
                Article article = new Article();
                article.setId(Long.valueOf(String.valueOf(i)));
                article.setTitle("ElasticSearch是一个基于Lucene的搜索服务器" + i);
                article.setContent("它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口" + i);
                String jsonStr = JSON.toJSON(article).toString();
                //批量添加数据
                IndexResponse indexResponse = transportClient.prepareIndex("blog5", "article", String.valueOf(article.getId())).setSource(jsonStr).get();
            }
            transportClient.close();
    }

13.2.4.3 修改文档

1、 prepareUpdate、prepareIndex

.prepareUpdate( index , type , id ).setDoc(jsonStr)

@Test
public void testUpdateDocumentByUpdate() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
    
        Article article = new Article();
        article.setId(2L);
        article.setTitle("Edsfsdf基于Lucene的搜索服务器222244");
        article.setContent("基胜多负少的水电费于RESTful web接口22334");

        String jsonStr = JSON.toJSON(article).toString();
        //jsonStr={"id":2,"title":"Edsfsdf基于Lucene的搜索服务器222244","content":"基胜多负少的水电费于RESTful web接口22334"}
        System.out.println("jsonStr=" + jsonStr);

        //修改内容
        UpdateResponse updateResponse = transportClient.prepareUpdate("bolg5", "article", String.valueOf(article.getId())).setDoc(jsonStr).get();//###
        System.out.println(updateResponse.status());//OK
        transportClient.close();
}

再一次赋值:

  @Test
    public void testUpdateDocument() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
        Article article = new Article();
        article.setId(2L);
        article.setTitle("再一次赋值");
        article.setContent("再一次赋值的内容");
        String jsonStr = JSON.toJSON(article).toString();

        //重新赋值该索引、类型和id
        IndexResponse indexResponse = transportClient.prepareIndex("bolg5", "article", String.valueOf(article.getId())).setSource(jsonStr).get();
        System.out.println(indexResponse.status());//OK
        transportClient.close();
    }

2、 update

.update(new UpdateRequest( index , type , id ).doc( json ))

@Test
public void testUpdateDocumentByUpdateRequest() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName( "127.0.0.1"), 9300));
        Article article = new Article();
        article.setId(2L);
        article.setTitle("update标题");
        article.setContent("update内容");
        String jsonStr = JSON.toJSON(article).toString();
        
        // update 方法修改
        UpdateResponse updateResponse = transportClient.update(new UpdateRequest("bolg5", "article", String.valueOf(article.getId())).doc(jsonStr)).get();
        System.out.println(updateResponse.status());//OK
        transportClient.close();
}

13.2.4.4 删除文档

1、 prepareDelete

.prepareDelete( index , type , id )

 @Test
public void testDeleteDocument() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
    
        // prepareDelete 删除数据
        DeleteResponse deleteResponse = transportClient.prepareDelete("bolg5", "article", "2").get();
        System.out.println(deleteResponse.status());
        transportClient.close();
}

2、 delete

.delete(new DeleteRequest( index , type , id ))

  /**
     * 删除文档
     */
    @Test
    public void testDeleteDocumentByDelRequest() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));

        //delete(new DeleteRequest("", "", "")) 删除
        DeleteResponse deleteResponse = transportClient.delete(new DeleteRequest("bolg5", "article", "1")).get();
        System.out.println(deleteResponse.status());
        transportClient.close();
    }

3、根据条件删除

DeleteByQueryAction.INSTANCE.newRequestBuilder( client )

.filter(QueryBuilders.matchQuery( field, XXX))

.source( index )

 	/**
     * 根据查询条件进行删除数据
     */
    @Test
    public void elasticsearchDeleteByQuery() {
         TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName( "127.0.0.1"), 9300));
        
        BulkByScrollResponse response = DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
                // 指定查询条件,matchQuery是name的值text里面包括了这个内容就进行删除。默认使用标准分词器。
                .filter(QueryBuilders.matchQuery("username", "王五五"))
                // 指定索引名称
                .source("people").get();
        // 获取到删除的个数
        long deleted = response.getDeleted();
        // 打印输出删除的个数
        System.out.println(deleted);
        //1
    }

4、异步删除

/**
     * 异步删除
     * 

* 监听,如果真正删除以后进行回调,打印输出删除确认的消息。 */ @Test public void elasticsearchDeleteByQueryAsync() { DeleteByQueryAction.INSTANCE.newRequestBuilder(client) .filter(QueryBuilders.matchQuery("sex", "男")) .source("people") .execute(new ActionListener() { // 删除以后的方法回调 @Override public void onResponse(BulkByScrollResponse response) { // 返回删除的个数 long deleted = response.getDeleted(); System.out.println("数据删除完毕!"); // 打印删除的个数 System.out.println("数据删除的个数: " + deleted); } @Override public void onFailure(Exception e) { // 失败打印异常信息 e.printStackTrace(); } }); // 先打印输出,正常执行完毕。再执行异步监听删除数据。 try { System.out.println("异步删除操作!"); // 休眠10秒钟,避免主线程里面结束,子线程无法进行结果输出 Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } }

13.3 简单查询

13.3.1 查询全部

QueryBuilders.matchAllQuery()

   /**
     * 查询全部
     */
    @Test
    public void testFindAll() throws Exception {
        //创建客户端访问对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
        //QueryBuilders.matchAllQuery(),查询全部
        SearchResponse response = transportClient.prepareSearch("blog5").setTypes("article")
                .setQuery(QueryBuilders.matchAllQuery())//###
                .get();
        //获取搜索结果
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        //遍历结果
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit : hits1) {
            System.out.println(hit.getSourceAsString());
        }
        transportClient.close();
    }  

13.3.2 字符串查询

QueryBuilders.queryStringQuery(“XXX”)

    /**
     * 字符串查询
     */
    @Test
    public void testQueryStirng() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
        SearchResponse response = transportClient.prepareSearch("blog5").setTypes("article")
                //利用IK分词器,匹配字符串内容
                .setQuery(QueryBuilders.queryStringQuery("是个"))//###
                .get();
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit : hits1) {
            System.out.println(hit.getSourceAsString());
        }
        transportClient.close();
    }

13.3.3 词条查询

QueryBuilders.termQuery(“content”, “XXX”)

    /**
     * 词条查询
     */
    @Test
    public void testQueryTerm() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
        SearchResponse response = transportClient.prepareSearch("blog").setTypes("article")
                .setQuery(QueryBuilders.termQuery("content", "创建"))//###
                .get();
        
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit : hits1) {
            System.out.println(hit.getSourceAsString());
        }
        transportClient.close();
    }

13.3.4 模糊查询

QueryBuilders.wildcardQuery(“title”," xxx ")

   /** 模糊查询 */
    @Test
    public void testWildcard() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));
        
        SearchResponse response = transportClient.prepareSearch("blog5").setTypes("article")
                .setQuery(QueryBuilders.wildcardQuery("title","*基于*"))//####
                .get();
        
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit : hits1) {
            System.out.println(hit.getSourceAsString());
        }
        transportClient.close();
    }

13.3.5 分页查询和排序

searchRequestBuilder.setFrom( 0)
searchRequestBuilder.setSize( 3)
searchRequestBuilder.addSort(“id”, SortOrder.DESC)

   /**
     * 查询分页和排序
     */
    @Test
    public void testQueryPageAndSort() throws Exception {
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300));

        //构造搜索内容, 默认每页10条记录
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("blog5") .setTypes("article").setQuery(QueryBuilders.matchAllQuery());

        //查询第1页数据,每页3条
        //setFrom():从第几条开始检索,默认是0。
        // setSize():每页最多显示的记录数。
        searchRequestBuilder.setFrom(0);//###
        searchRequestBuilder.setSize(3);//###
        //排序
        searchRequestBuilder.addSort("id", SortOrder.DESC);

        SearchResponse searchResponse = searchRequestBuilder.get();
        // 获取命中次数,查询结果有多少对象
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
        transportClient.close();
    }

输出:

13.3.6 多条查询

.prepareMultiGet() .add( index , type , id )

 /**
     * 查找多条
     * 

* 索引Index里面的类型Type里面的多个id的所有信息 */ @Test public void elasticsearchMultiGet() throws IOException { TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY) .addTransportAddress(new InetSocketTransportAddress( InetAddress.getByName("127.0.0.1"), 9300)); // 查询出多个索引Index、多个类型Type的多个id的所有信息 MultiGetResponse multiGetItemResponses = client.prepareMultiGet() .add("people", "student", "1") .add("people", "student", "2", "3") .add("people", "teacher", "1") //不存在该索引,.isExists()报错 .add("news", "fulltext", "1") .get(); // 将查询出的结果遍历输出 for (MultiGetItemResponse itemResponse : multiGetItemResponses) { // 将每一个查询出的结果遍历输出 GetResponse response = itemResponse.getResponse(); // 判断如果存在就进行遍历输出 if (response.isExists()) { String json = response.getSourceAsString(); System.out.println(json); } } }

13.3.7 范围查找

rangeQuery( field ).from( XX ).to( XX ).includeLower( boolean ).includeUpper( boolean )

    /**
     * 按照范围进行查找。
     */
    @Test
    public void elasticsearchRange() {
        // includeLower(true).includeUpper(false)含义是包含前面,不包含后面的
        // [21, 24)
        QueryBuilder qb = rangeQuery("age").from(21).to(24).includeLower(true).includeUpper(false);
        // 将查询条件传递进去,并将查询结果进行返回。
        SearchResponse response = client.prepareSearch("people").setQuery(qb).get();
        System.out.println(response);
    }

13.3.11 查询结果高亮

   /**
     * 处理高亮
     */
    @Test
    public void testHighLight() throws Exception {
        //创建Client连接对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        //构造搜索内容
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("blog5").setTypes("article")
                //.setQuery(QueryBuilders.termQuery("content","搜索"));
                //模糊搜索
                .setQuery(QueryBuilders.wildcardQuery("content", "*索"));
        searchRequestBuilder.setFrom(3);
        searchRequestBuilder.setSize(3);
        searchRequestBuilder.addSort("id", SortOrder.DESC);

        //设置高亮数据
        HighlightBuilder highLighter = new HighlightBuilder();
        highLighter.preTags("");
        highLighter.field("content");
        highLighter.postTags("");
        searchRequestBuilder.highlighter(highLighter);

        //获得查询结果数据
        SearchResponse searchResponse = searchRequestBuilder.get();
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println("SourceAsString内容:" + hit.getSourceAsString());
            Text[] texts = hit.getHighlightFields().get("content").getFragments();
            for (Text text : texts) {
                System.out.println("content内容:" + text.toString());
            }
            System.out.println("--------------------------------------");
        }
        transportClient.close();
    }

13.3.12 简单查询

.prepareGet( index , type , id).execute().actionGet()

    @Test
    public void testSelect() {
        try {
        //设置集群名称elasticsearch,Settings设置es的集群名称,使用的设计模式,链式设计模式、build设计模式。
            Settings settings=Settings.builder()
                    .put("cluster.name","elasticsearch") //集群名
                    .build();

            // 读取es集群中的数据,创建client。
            @SuppressWarnings("resource")
            TransportClient client = new PreBuiltTransportClient(settings).addTransportAddresses(
                    // 用java访问ES用的端口是9300。es的9200是restful的请求端口号
                    // 由于我使用的是伪集群,所以就配置了一台机器,如果是集群方式,将竞选主节点的加进来即可。
                    new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
            
            // 方式是先去索引里面查询出索引数据,再去文档里面查询出数据。####
            GetResponse response = client.prepareGet("blog5", "article", "14").execute().actionGet();
            System.out.println(response);
            // 关闭client
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

查询的结果如下所示:

13.4 设置

是否创建索引,是否存储,是否即分词,又建立索引(analyzed)、是否建索引不分词(not_analyzed)等等。

13.4.1 设置集群、索引

    private TransportClient client = new PreBuiltTransportClient(Settings.EMPTY).addTransportAddresses(
            new InetSocketTransportAddress(InetAddress.getByN