Elasticsearch 07 使用SpringBoot集成Elasticsearch

1、Maven依赖


    org.springframework.boot
    spring-boot-starter-parent
    1.5.6.RELEASE



    5.6.0
    2.7



    
    
        org.springframework.boot
        spring-boot-starter-web
    
    
    
        org.elasticsearch.client
        transport
        ${elasticsearch.version}
    
    
    
        org.apache.logging.log4j
        log4j-core
        ${log4j.version}
    

    这里SpringBoot使用的1.5.6.RELEASE版本,Elasticsearch的TransportClient是5.6.0版本,log4j是2.7版本

2、TransportClient

⑴ 概念

    TransportClient是操作Elasticsearch集群的客户端API,它通过异步方式和ES集群进行交互

⑵ API

① 步骤

    在application.yml中配置ES的服务地址【master的】和端口号【默认为9300】
    创建Configuration配置类,使用@Configuration和@ConfigurationProperties(prefix = “配置的前缀”) 2个注解,声明属性,并提供对应的set方法
    提供一个获取TransportClient的方法,并使用@Bean注解

② PreBuiltTransportClient

    用于创建TransportClient,使用预先安装好的插件(可选的)
    通过addTransportAddress(TransportAddress transportAddress) {}方法,添加服务传输地址。需要传递一个InetSocketTransportAddress对象

    public InetSocketTransportAddress(InetAddress address, int port) {}
        传入ES的服务地址和端口即可

③ Settings

    用于创建TransportClient时,所配置的参数。它有一个Map属性,用于存放配置

    // we use a sorted map for consistent serialization when using getAsMap()
    private final Map map = new TreeMap<>();

    例如:当修改了默认的集群名称(elasticsearch)时,需要配置cluster.name ,并指定新的集群名称

⑶ 示例

【application.yml】

es:
  host: ???.???.???.???
  port: 9300

【配置类】

@Configuration
@ConfigurationProperties(prefix = "es")
public class MyConfig {

    private String host;

    private Integer port;

    @Bean
    public TransportClient getTransportClient() throws UnknownHostException {
        TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(host), port);
        Settings settings = Settings.builder().put("cluster.name", "集群名称").build();
        TransportClient transportClient = new PreBuiltTransportClient(settings);
        transportClient.addTransportAddress(transportAddress);
        return transportClient;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

}

3、增加操作

⑴ API

① XContentBuilder

    用于创建请求JSON的建造者类

    通过XContentFactory工厂类来创建
    调用XContentFactory的jsonBuilder方法,其次调用startObject方法,表示要开始创建对象了,并通过field(String name, Object value) 方法给对象的属性赋值,最后调用endObject方法,表示对象创建完毕

② IndexResponse

    通过调用TransportClient的prepareIndex(String index, String type) 方法,创建新的文档
        传入索引和类型

    其次再调用setSource方法,将生成的XContentBuilder传入
    最后调用get 方法获取响应对象

    Tips:可以通过IndexResponse的status方法,获取响应状态,通过RestStatus枚举类中的CREATED状态,来判断创建新文档是否成功

⑵ 注意事项

    对于date类型的字段,如果使用java的Date转换后的字符串类型来存储,会减去8个小时,因为默认是按照UTC时区算的
    所以推荐使用java.util.Date的getTime() 方法获取的毫秒数,这样就不会有时区的误差了

⑶ 示例

        XContentBuilder sourceBuilder = XContentFactory.jsonBuilder()
                                                       .startObject()
                                                       .field("字段", "值")
                                                       .endObject();
        IndexResponse indexResponse = transportClient.prepareIndex("索引", "类型")
                                                      .setSource(sourceBuilder).get();
        if (RestStatus.CREATED.equals(indexResponse.status())) {
            System.out.println("创建成功!");
        } else {
            System.out.println("创建失败!");
        }

4、更新操作

⑴ API

    UpdateResponse
    通过调用TransportClient的prepareUpdate(String index, String type, String id) 方法
        传入索引、类型和要更新的文档的ID

    再调用setDoc(XContentBuilder source) 方法
    和保存时类似,传入XContentBuilder对象

    最后调用get方法获取响应对象

    同样地可以通过RestStatus枚举类的OK 来判断响应的状态是否更新成功

⑵ 示例

    XContentBuilder source = XContentFactory.jsonBuilder()
                                            .startObject()
                                            .field("字段", "值")
                                            .endObject();
    UpdateResponse updateResponse = transportClient.prepareUpdate("索引", "类型", "要更新的文档的ID")
                                                    .setDoc(source)
                                                    .get();
    if (RestStatus.OK.equals(updateResponse.status())) {
        System.out.println("更新文档成功!");
    } else {
        System.out.println("更新文档失败!");
    }

5、删除操作

⑴ API

① DeleteResponse

    调用TransportClient的prepareDelete(String index, String type, String id) 方法
    传入索引、类型、要删除的文档的ID

    再调用get方法获取响应对象

    可以通过RestStatus的OK 来判断是否删除成功

② AdminClient

    针对集群的管理员操作客户端
    通过TransportClient的admin() 方法来获取

③ IndicesAdminClient indices();

    AdminClient的方法,可以操作多个索引

④ DeleteIndexRequestBuilder prepareDelete(String… indices);

    IndicesAdminClient的方法,可以删除多个索引

    Tips:传入 “_all” 可以删除所有的索引

⑤ ListenableActionFuture execute();

    执行删除索引操作

⑥ T actionGet();

AdapterActionFuture 的方法,

    用于获取DeleteIndexResponse对象

⑦ public final boolean isAcknowledged();

    用于判断删除索引是否成功。通过DeleteIndexResponse对象来调用

⑵ 示例

【删除一个文档】

    DeleteResponse deleteResponse = transportClient.prepareDelete("索引", "类型", "要删除的文档的ID").get();
    if (RestStatus.OK.equals(deleteResponse.status())) {
        System.out.println("删除文档成功!");
    } else {
        System.out.println("删除文档失败!");
    }

【删除一个索引】

    DeleteIndexResponse deleteIndexResponse = transportClient.admin()
                                                             .indices()
                                                             .prepareDelete("要删除的索引")
                                                             .execute()
                                                             .actionGet();
    if (deleteIndexResponse.isAcknowledged()) {
        System.out.println("删除索引成功!");
    } else {
        System.out.println("删除索引失败!");
    }

6、简单查询

⑴ API

① GetResponse

    通过TransportClient调用GetRequestBuilder prepareGet(String index, String type, String id) 方法
    传入索引、类型和要查询的文档的ID

    再调用get方法,可以获取响应对象

② public Map getSource();

    获取响应的文档JSON内容,由JSON的key和value组成的Map。通过GetResponse调用

⑵ 示例

    GetResponse getFields = transportClient.prepareGet("索引", "类型", "要查询的文档的ID").get();
    Map source = getFields.getSource();
    source.forEach((k, v) -> {System.out.println(k + " : " + v);});

7、复合查询

⑴ API

① BoolQueryBuilder

    用于创建过滤条件查询器

② public BoolQueryBuilder must(QueryBuilder queryBuilder);

    创建必须满足条件的查询器。需要传入查询创建器

③ public BoolQueryBuilder should(QueryBuilder queryBuilder);

    创建可选满足条件的查询器。需要传入查询创建器

④ QueryBuilders

    查询创建器,可以创建多种查询类型的查询器

        ⒈ MatchQueryBuilder matchQuery(String name, Object text);
            匹配查询器。需要传入字段和要模糊匹配的内容

        ⒉ TermsQueryBuilder termsQuery(String name, Collection values);
            多个匹配查询器。需要传入字段和要精确匹配的内容的集合

        ⒊ RangeQueryBuilder rangeQuery(String name);
            范围查询器。需要传入字段

            RangeQueryBuilder from(Object from);
                设置范围的起始条件

            RangeQueryBuilder to(Object to);
                设置范围的终止条件

            RangeQueryBuilder gte(Object from);
                设置范围要大于等于的条件

            RangeQueryBuilder lt(Object to)
                设置范围要小于的条件

⑤ BoolQueryBuilder filter(QueryBuilder queryBuilder);

    过滤查询器。需要传入查询创建器

⑥ SearchRequestBuilder prepareSearch(String… indices);

    调用复合查询的方法,可以获取查询请求创建器。需要传入一个或多个索引

⑦ SearchRequestBuilder setSearchType(SearchType searchType);

    设置查询的类型

        ⒈ SearchType.DFS_QUERY_THEN_FETCH
            当数据量不是很多时,可以选择此模式
            它会匹配最精确的评分(分数高的)

        ⒉ SearchType.QUERY_THEN_FETCH
            数据量多时,可以选择此查询类型
            它会查询所有的分片,根据查询的条件返回对应的文档内容,此外还会匹配指定的返回文档的数量。所以在数据量很大时,它的效率是高的

⑧ SearchRequestBuilder setFrom(int from);

    设置查询的起始索引位置。默认为0,且不能小于0,否则报错

⑨ SearchRequestBuilder setSize(int size);

    设置查询的文档的返回数量。默认为10

⑩ SearchResponse

    查询响应结果对象。通过SearchRequestBuilder(查询请求创建器)的get 方法来获取

⑾ SearchHits

    查询到的结果集对象。通过SearchResponse来调用

⑿ public long getTotalHits();

    获取查询到的文档的总的数量【该数量和最终返回的文档数量可能不一致。如果没有设置size,则默认返回10,否则就返回size个文档】
    通过SearchHits来调用

⒀ public SearchHit[] getHits();

    获取查询到的结果集数组。通过SearchHits来调用【这才是最终返回的结果集】

⒁ SearchHit

    public Map getSource()
    获取每一个文档对应的Map类型的结果。通过SearchHit来调用

⑵ 示例

    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
    boolQueryBuilder.must(QueryBuilders.matchQuery("字段", "要模糊匹配的内容"));
    boolQueryBuilder.must(QueryBuilders.termQuery("字段", "要精确匹配的内容"));
    boolQueryBuilder.should(QueryBuilders.termsQuery("字段", Arrays.asList("要精确匹配的内容1", "要精确匹配的内容2")));

    RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("字段");
    rangeQueryBuilder.from("范围起始内容");
    rangeQueryBuilder.to("范围终止内容");
    // rangeQueryBuilder.gt("范围要大于的内容");
    // rangeQueryBuilder.lte("范围要小于等于的内容");
    boolQueryBuilder.should(rangeQueryBuilder);

    SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("索引")
                                                                .setQuery(boolQueryBuilder)
                                                                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) // 文档数量不是很多
                                                                .setFrom(0) // 从0开始查询
                                                                .setSize(10); // 最终返回10个文档

    System.out.println("查询JSON:\n" + searchRequestBuilder.toString());

    SearchResponse searchResponse = searchRequestBuilder.get(); // 获取查询响应对象
    SearchHits searchHits = searchResponse.getHits();
    long totalHits = searchHits.getTotalHits();
    System.out.println("匹配到的文档的总数:" + totalHits);

    if (0 < totalHits) {
        SearchHit[] hits = searchHits.getHits();
        Map source;
        for (SearchHit searchHit : hits) {
            source = searchHit.getSource();
            source.forEach((k, v) -> {System.out.println(k + " : " + v);});
        }
    }

你可能感兴趣的:(Elasticsearch,elasticsearch,lucene,spring-boot,倒排索引)