官方文档:Java Transport Client (deprecated) [7.17] | Elastic
在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的操作了。
还有对应的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的操作了。
以上是最长用的两个客户端。
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 serverList) {
JestClientFactory jestClientFactory = new JestClientFactory();
HttpClientConfig.Builder httpClientConfigBuilder = new HttpClientConfig.Builder(serverList);
jestClientFactory.setHttpClientConfig(httpClientConfigBuilder.build());
JestHttpClient jestHttpClient = (JestHttpClient) jestClientFactory.getObject();
return jestHttpClient;
}
HttpClientConfig
参数 | 说明 | 备注 |
---|---|---|
serverList | ES集群机器列表 | |
isMultiThreaded | 是否使用HttpClient连接池 | |
isDiscoveryEnabled | 是否开启节点侦测 | 建议使用该参数,当集群中机器下线,可以检测到并更新机器列表 |
discoveryFilter | ||
isRequestCompressionEnabled | 是否开启GZIP压缩请求 | 需要ES节点设置 http.compression |
connTimeout | HttpClient的connTimeout | |
readTimeout | HttpClient的readTimeout | |
discoveryFrequency | 节点侦测的频率 | |
maxConnectionIdleTime | ||
discoveryFrequencyTimeUnit | 节点侦测的频率单位 | TimeUnit |
maxConnectionIdleTimeDurationTimeUnit | ||
gson | ||
defaultSchemeForDiscoveredNodes | ||
maxTotalConnection | HttpClient连接池的最大连接数 | |
defaultMaxTotalConnectionPerRoute | HttpClient连接池每个路由的默认最大连接数 | |
maxTotalConnectionPerRoute | HttpClient连接池路由的最大连接数 | 会覆盖defaultMaxTotalConnectionPerRoute的默认值 |
credentialsProvider | ||
sslSocketFactory | ||
plainSocketFactory | ||
httpRoutePlanner | ||
proxyAuthenticationStrategy | ||
httpIOSessionStrategy | ||
httpsIOSessionStrategy | ||
preemptiveAuthTargetHosts |
都是建立在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 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());
}
}
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
重写需要用到的方法即可使用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 {
@Override
public Iterable findAll();
@Override
Optional findById(String s);
@Override
void deleteById(String s);
@Override
void deleteAll(Iterable extends test> entities);
@Override
void deleteAll();
@Override
Page search(SearchQuery searchQuery);
@Override
Page search(QueryBuilder queryBuilder, Pageable pageable);
}
类如Page
就可以在业务层调用。然后使用**QueryBuilder(BoolQueryBuilder ,MatchQueryBuilder ..)进行查询逻辑的编写。并设置Pageable进行分页和排序。将这两个参数传入即可得到查询的结果。
常用方法:
//进行单个值得精确匹配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")))
......
可以进行多条件判断查询
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进行更复杂的查询。
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()中...。进行复制查询并获得对应的返回结果。
主要使用它的实现类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);
import org.springframework.data.domain.Sort;
Sort sort = Sort.by(Sort.Direction.ASC,"需要排序的字段");
Sort sort = Sort.by(Sort.Direction.DESC,"update_time")