SpringBoot中Elasticsearch客户端及API使用

官方文档:Java Transport Client (deprecated) [7.17] | Elastic

1.创建客户端

(1)TransportClient

在ES 7.0版本中将弃用TransportClient客户端,且在8.0版本中完全移除它

创建步骤:

//直接在http://127.0.0.1:9200/ 中可以看到es对应的cluster_name
Settings settings= Settings.builder()
    .put("cluster.name","这里是es对应的cluster_name").build(); 
TransportClient transportClient=new PreBuiltTransportClient(settings);
transportClient.addTransportAddress(new 
          TransportAddress(InetAddress.getByName("127.0.0.1"),9300));

然后就可以通过transportClient来进行es的操作了。

(2)RestHighLevelClient

还有对应的RestLowLevelClient低级客户端不过没有多少使用者。

RestHighLevelClient是官方新推出的,使用Http连接查询结果,因此需要9200端口。是RestFul风格

RestHighLevelClient restHighLevelClient(){
    RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
            new HttpHost("127.0.0.1", 9200, "http")));
    return client;
}

然后就可以通过client来进行es的操作了。

以上是最长用的两个客户端。

(3)Jest

Github: GitHub - searchbox-io/Jest: Elasticsearch Java Rest Client.

如果在项目中使用了不同版本的ES集群,那么使用原生的客户端那么会是一个问题。如果ES的版本不是问题,那么还是建议使用原生的客户端会更好一些。 ES没有Rest客户端,所以Jest出现的原因。

Maven Repository: Index of /groups/public/io/searchbox/jest 从 5.x 版本开始最低要求使用JDK8

/**
     * 简单构建一个 Jestclient
     *
     * @param serverList es集群机器列表,每一台机器形如: http://xxx.xxx.xxx:9200
     * @return
     */
public static JestHttpClient getJestHttpClient(List<String> serverList) {
    JestClientFactory jestClientFactory = new JestClientFactory();
​
    HttpClientConfig.Builder httpClientConfigBuilder = new                                          HttpClientConfig.Builder(serverList);
​
    jestClientFactory.setHttpClientConfig(httpClientConfigBuilder.build());
​
    JestHttpClient jestHttpClient = (JestHttpClient) jestClientFactory.getObject();
​
    return jestHttpClient;
}

HttpClientConfig

参数说明备注
serverListES集群机器列表
isMultiThreaded是否使用HttpClient连接池
isDiscoveryEnabled是否开启节点侦测建议使用该参数,当集群中机器下线,可以检测到并更新机器列表
discoveryFilter
isRequestCompressionEnabled是否开启GZIP压缩请求需要ES节点设置 http.compression
connTimeoutHttpClient的connTimeout
readTimeoutHttpClient的readTimeout
discoveryFrequency节点侦测的频率
maxConnectionIdleTime
discoveryFrequencyTimeUnit节点侦测的频率单位TimeUnit
maxConnectionIdleTimeDurationTimeUnit
gson
defaultSchemeForDiscoveredNodes
maxTotalConnectionHttpClient连接池的最大连接数
defaultMaxTotalConnectionPerRouteHttpClient连接池每个路由的默认最大连接数
maxTotalConnectionPerRouteHttpClient连接池路由的最大连接数会覆盖defaultMaxTotalConnectionPerRoute的默认值
credentialsProvider
sslSocketFactory
plainSocketFactory
httpRoutePlanner
proxyAuthenticationStrategy
httpIOSessionStrategy
httpsIOSessionStrategy
preemptiveAuthTargetHosts

2.SearchRequest,BulkRequest..

都是建立在RestHighLevelClient高级restful风格客户端的前提下。取得上方的client

@Autowired
    private RestHighLevelClient restHighLevelClient;
​
    //PUT testCreate
    @Test
    void testCreate() throws IOException {
        //1.创建索引请求
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("test_create");
        //2.执行创建请求    IndicesClient,请求后获得响应
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse);
    }
​
    //测试获取索引,判断其是否存在
    @Test
    void getEs() throws IOException {
        GetIndexRequest test_create = new GetIndexRequest("test_create");
        boolean exists = restHighLevelClient.indices().exists(test_create, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
​
    //测试删除索引
    @Test
    void deleteEs() throws IOException {
        DeleteIndexRequest test_create = new DeleteIndexRequest("test_create");
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(test_create, RequestOptions.DEFAULT);
        System.out.println(delete);
    }
​
    //测试添加文档
    @Test
    void AddEsWd() throws IOException {
        //创建实体类对象
        User user = new User("我是测试集成java",12);
        //创建请求
        IndexRequest test_create = new IndexRequest("test_create");
        //创建规则
        test_create.id("1");
        test_create.timeout(TimeValue.timeValueSeconds(1));
        //超出1s就不执行
        test_create.timeout("1s");
        //将数据放入请求 这里使用fastjson,不过推荐使用hutoool工具类
        IndexRequest source = test_create.source(JSON.toJSONString(user), XContentType.JSON);
        //客户端发送请求
        IndexResponse index = restHighLevelClient.index(source, RequestOptions.DEFAULT);
        //获取相应的结果
        System.out.println(index.toString());   //IndexResponse[index=test_create,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
        System.out.println(index.status()); //CREATED
    }
​
    //测试获取文档
    @Test
    void getWd() throws IOException {
        GetRequest test_create = new GetRequest("test1", "1");
        //不获取返回的_source上下文效率更高
        test_create.fetchSourceContext(new FetchSourceContext(false));
        test_create.storedFields("_none_");
​
        boolean exists = restHighLevelClient.exists(test_create, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
​
    //测试获取文档的信息
    @Test
    void getWdXx() throws IOException {
        GetRequest test_create = new GetRequest("test_create", "1");
        GetResponse exists = restHighLevelClient.get(test_create, RequestOptions.DEFAULT);
        System.out.println(exists);//返回全部的内容
        System.out.println(exists.getSource());//获取source中的信息 {name=我是测试集成java, age=12}
        System.out.println(exists.getVersion());//获取版本
        System.out.println(exists.getSourceAsString());//打印文档的内容 {"age":12,"name":"我是测试集成java"}
    }
​
    //更新文档的信息
    @Test
    void updateWdXx() throws IOException {
        UpdateRequest test_create = new UpdateRequest("test_create","1");
        User user = new User("更新测试", 12);
        test_create.doc(JSON.toJSONString(user),XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(test_create, RequestOptions.DEFAULT);
        System.out.println(update);
    }
​
    //删除文档记录
    @Test
    void deleteWdXx() throws IOException {
        DeleteRequest test_create = new DeleteRequest("test_create", "1");
        DeleteResponse delete = restHighLevelClient.delete(test_create, RequestOptions.DEFAULT);
        System.out.println(delete);
    }
​
    //真实的项目需要批量的插入数据
    @Test
    void testBulkRequest() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");
        ArrayList<User> users = new ArrayList<>();
        users.add(new User("test1",1));
        users.add(new User("test2",2));
        users.add(new User("test3",3));
        users.add(new User("test4",4));
        users.add(new User("test5",5));
        //批处理请求
        int i = 1;
        for (User user : users){
            i++;
            bulkRequest.add(new IndexRequest("test_create")
                    .id(""+i) //不写id的话就会生出随机的id
                    .source(JSON.toJSONString(user),XContentType.JSON));
        }
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulk);
        System.out.println(bulk.hasFailures());//是否失败 false成功
    }
​
    //查询
    @Test
    void testSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("test_create");
        //构建搜索的条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建一个query构造器,进行分组查询
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name","test");
        searchSourceBuilder.query(matchQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        //RequestOptions.DEFAULT默认值
        SearchResponse search = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        System.out.println(search.getHits());
        System.out.println("=======================");
        for (SearchHit hit : search.getHits()){
            System.out.println(hit.getSourceAsString());
        }
    }

3.ElasticsearchRepository<T, String>

TransportClient客户端进行使用,RestHighLevelClient没测试过应该也可以。

es操作引用库。

T代表的是索引对应的实体类,其中存放索引中需要返回的字段和对应的getset方法和有参和无参构造方法。

可以直接使用lombok中的注解添加相应的getset和构造方法

import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
​
@Getter
@Setter
@ToString
@AllArgsConstructor     //有参
@NoArgsConstructor      //无参
//@Document(indexName = "test", type = "_doc")
@Document(indexName = "索引名称", type = "类型")
public class test implements Serializable {
    @Id
    private String id;// 索引中的主键id
​
    private String name; 
​
    private Date birthday;
}

然后再创建一个dao层实现ElasticsearchRepository<test, String>

重写需要用到的方法即可使用service中调用dao层中方法来进行相应的搜索。

import com.hyq.test;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
​
import java.util.Optional;
​
public interface test extends ElasticsearchRepository<ELKZFJD, String> {
    @Override
    public Iterable<test> findAll();
​
    @Override
    Optional<test> findById(String s);
​
    @Override
    void deleteById(String s);
​
    @Override
    void deleteAll(Iterable<? extends test> entities);
​
    @Override
    void deleteAll();
​
    @Override
    Page<test> search(SearchQuery searchQuery);
​
    @Override
    Page<test> search(QueryBuilder queryBuilder, Pageable pageable);
​
}

类如Page<test> search(QueryBuilder queryBuilder, Pageable pageable);

就可以在业务层调用。然后使用**QueryBuilder(BoolQueryBuilder ,MatchQueryBuilder ..)进行查询逻辑的编写。并设置Pageable进行分页和排序。将这两个参数传入即可得到查询的结果。

4.QueryBuilder

常用方法:

//进行单个值得精确匹配termQuery("key", obj) 完全匹配
QueryBuilders.termQuery("name","我是中国人")
    
//进行模糊查询multiMatchQuery("key.keyword", "*field1*"); 可以使用通配符.keyword是否添加查看上方的    Es的常见问题
QueryBuilders.wildcardQuery("name"/"name.keyword","*我是中*")
    
//进行多个值得精确匹配termsQuery("key", obj1, obj2..)   一次匹配多个值
String[] a = {"a","ab","ac","qq"}
QueryBuilders.termsQuery("name",a)
    
//模糊查询  和wildcardQuery对比的话不能使用通配符
QueryBuilders.matchQuery("name","我是")
    
//matchPhraseQuery对中文精确匹配
queryBuilders.matchPhraseQuery("key", value)
    
//进行布尔查询
QueryBuilders.boolQuery()
    
//进行模糊查询
QueryBuilders.boolQuery()
    
//进行范围查询 gte大于等于,lte小于等于 gt大于 lt小于
QueryBuilders.rangeQuery("age")
    .gte(jsonObjectEq.get("1"))
    .lte(jsonObjectEq.get("10")))
......

(1)BoolQueryBuilder

可以进行多条件判断查询

BoolQueryBuilder builder = QueryBuilders.boolQuery();
//must其中的条件必须满足 and
builder.must(queryBuilders.matchPhraseQuery("key", value));
//mustNot其中的条件必须不满足 not
builder.mustNot(queryBuilders.matchPhraseQuery("key", value));
//should其中的条件满足一个即可 or
builder.should(queryBuilders.matchPhraseQuery("key", value));
builder.should(QueryBuilders.matchQuery("name","我是"));

当同时使用must和should时,minumum_should_match默认是0。所以should就不会生效。

boolQueryBuilder.minimumShouldMatch(1)将其修改为1就可以解决这个问题。

然后再将其放置到NativeSearchQueryBuilder.withQuery(builder)。使用NativeSearchQueryBuilder进行更复杂的查询。

(2)NativeSearchQueryBuilder

NativeSearchQuery是一个原生的查询条件类,用来和ES的一些原生查询方法进行搭配,实现一些比较复杂的查询。

NativeSearchQueryBuilder可以进行复杂的查询设置。

 NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //将搜索条件设置到构建中
        nativeSearchQueryBuilder.withQuery(builder);
        //将分页设置到构建中
        nativeSearchQueryBuilder.withPageable(page);
        //将排序设置到构建中(本人尝试不太好使,不如直接在Pageable中设置再放置到上方的分页中)
        nativeSearchQueryBuilder.withSort(sort);
        //生产NativeSearchQuery
        NativeSearchQuery query = nativeSearchQueryBuilder.build();

然后将query放入search方法或者SearchRequestBuilder.query()中...。进行复制查询并获得对应的返回结果。

5.Pageable

主要使用它的实现类PageRequest。

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
​
//page为当前的页数,length为一页多少数据,sort为排序(详情见下一节)
Pageable page1 = PageRequest.of(page, length, sort);
//也可以不设置排序
Pageable page1 = PageRequest.of(page, length);

6.Sort

import org.springframework.data.domain.Sort;
​
Sort sort = Sort.by(Sort.Direction.ASC,"需要排序的字段");
Sort sort = Sort.by(Sort.Direction.DESC,"update_time")

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个名字还中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值