1.介绍
Jest是一个java http rest ES客户端。
ES官方有三种客户端:java api、high level client、low level client
java api在ES近几个大版本中逐渐被官方淘汰,而剩余两种客户端需要手动拼接和解析json,不太方便使用。相较于官方rest客户端,jest的api操作方式不用手动拼接json,易用性更好。
jest官方文档:https://github.com/searchbox-io/Jest/tree/master/jest
2.maven依赖
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.3</version>
</dependency>
3.使用
3.1.创建client
3.1.1.普通client
// Construct a new Jest client according to configuration via factory
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig
.Builder("http://localhost:9200")
.multiThreaded(true)
//Per default this implementation will create no more than 2 concurrent connections per given route
.defaultMaxTotalConnectionPerRoute(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_PER_ROUTE>)
// and no more 20 connections in total
.maxTotalConnection(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_TOTAL>)
.build());
JestClient client = factory.getObject();
- JestClient可以复用,无需每次请求都创建。
3.1.2.集群节点发现
//enable host discovery
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig.Builder(Arrays.asList("http://192.168.0.88:9200", "http://192.168.0.172:9200"))
//开启节点发现
.discoveryEnabled(true)
//节点发现轮询时间
.discoveryFrequency(1l, TimeUnit.MINUTES)
//节点过滤
.discoveryFilter("type:arbitrary")
.build()
);
3.1.3.http/ssl连接
// trust ALL certificates
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
// skip hostname checks
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
SchemeIOSessionStrategy httpsIOSessionStrategy = new SSLIOSessionStrategy(sslContext, hostnameVerifier);
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig.Builder("https://localhost:9200")
.defaultSchemeForDiscoveredNodes("https") // required, otherwise uses http
.sslSocketFactory(sslSocketFactory) // this only affects sync calls
.httpsIOSessionStrategy(httpsIOSessionStrategy) // this only affects async calls
.build()
);
3.1.4.用户认证
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(
new HttpClientConfig.Builder("http://localhost:9200")
.defaultCredentials("global_user", "global_password")
.build()
);
3.1.5.多节点分别进行用户认证
BasicCredentialsProvider customCredentialsProvider = new BasicCredentialsProvider();
customCredentialsProvider.setCredentials(
new AuthScope("192.168.0.88", 9200),
new UsernamePasswordCredentials("eu_user", "123")
);
customCredentialsProvider.setCredentials(
new AuthScope("192.168.0.172", 9200),
new UsernamePasswordCredentials("us_user", "456")
);
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(
new HttpClientConfig.Builder(Arrays.asList("http://192.168.0.88:9200", "http://192.168.0.172:9200"))
.credentialsProvider(customCredentialsProvider)
.build()
);
3.1.6.查看节点信息(包含ES版本号)
NodesInfo nodesInfo = new NodesInfo.Builder().build();
client.execute(nodesInfo);
3.2.创建index
3.2.1.简单创建index
client.execute(new CreateIndex.Builder("articles").build());
3.2.2.使用json形式设置索引settings
String settings = "\"settings\" : {\n" +
" \"number_of_shards\" : 5,\n" +
" \"number_of_replicas\" : 1\n" +
" }\n";
client.execute(new CreateIndex.Builder("articles").settings(Settings.builder().loadFromSource(settings).build().getAsMap()).build());
3.2.3.使用SettingsBuilder
设置索引settings
SettingsBuilder
为ES自带的api。
import org.elasticsearch.common.settings.Settings;
Settings.Builder settingsBuilder = Settings.builder();
settingsBuilder.put("number_of_shards",5);
settingsBuilder.put("number_of_replicas",1);
client.execute(new CreateIndex.Builder("articles").settings(settingsBuilder.build().getAsMap()).build());
3.2.4.获取所有索引
Cat cat = new Cat.IndicesBuilder().build();
client.execute(cat);
3.3.创建索引mapping
3.3.1.使用json形式创建mapping
PutMapping putMapping = new PutMapping.Builder(
"my_index",
"my_type",
"{ \"my_type\" : { \"properties\" : { \"message\" : {\"type\" : \"string\", \"store\" : \"yes\"} } } }"
).build();
client.execute(putMapping);
3.3.2.使用DocumentMapper.Builder
创建mapping
DocumentMapper.Builder
为ES自带api。
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
RootObjectMapper.Builder rootObjectMapperBuilder = new RootObjectMapper.Builder("my_mapping_name").add(
new StringFieldMapper.Builder("message").store(true)
);
DocumentMapper documentMapper = new DocumentMapper.Builder("my_index", null, rootObjectMapperBuilder).build(null);
String expectedMappingSource = documentMapper.mappingSource().toString();
PutMapping putMapping = new PutMapping.Builder(
"my_index",
"my_type",
expectedMappingSource
).build();
client.execute(putMapping);
3.4.写documents
3.4.1.使用json形式写数据
String source = "{\"user\":\"kimchy\"}";
3.4.2.使用JSONBuilder
写数据
JSONBuilder
为ES自带api。
String source = jsonBuilder()
.startObject()
.field("user", "kimchy")
.field("postDate", "date")
.field("message", "trying out Elastic Search")
.endObject().string();
3.4.3.使用map写数据
Map<String, String> source = new LinkedHashMap<String,String>();
source.put("user", "kimchy");
3.4.4.使用bean写数据
Article source = new Article();
source.setAuthor("John Ronald Reuel Tolkien");
source.setContent("The Lord of the Rings is an epic high fantasy novel");
Index index = new Index.Builder(source).index("twitter").type("tweet").build();
client.execute(index);
使用@JestId
注解可以指定bean的id,如果值是null,会注入ES内部生成的_id。
class Article {
@JestId
private String documentId;
}
使用@JestVersion
注解可以指定bean的documents版本(_version)
class Article {
@JestId
private String documentId;
@JestVersion
private Long documentVersion;
}
3.5.搜索documents
3.5.1.使用json搜索数据
String query = "{\n" +
" \"query\": {\n" +
" \"filtered\" : {\n" +
" \"query\" : {\n" +
" \"query_string\" : {\n" +
" \"query\" : \"test\"\n" +
" }\n" +
" },\n" +
" \"filter\" : {\n" +
" \"term\" : { \"user\" : \"kimchy\" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Search search = new Search.Builder(query)
// multiple index or types can be added.
.addIndex("twitter")
.addType("tweet")
.build();
SearchResult result = client.execute(search);
3.5.2.使用模板搜索数据
String query = "{\n" +
" \"id\": \"myTemplateId\"," +
" \"params\": {\n" +
" \"query_string\" : \"search for this\"" +
" }\n" +
"}";
Search search = new Search.TemplateBuilder(query)
// multiple index or types can be added.
.addIndex("twitter")
.addType("tweet")
.build();
SearchResult result = client.execute(search);
3.5.3.使用SearchSourceBuilder
搜索数据
SearchSourceBuilder
为ES自带api。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("user", "kimchy"));
Search search = new Search.Builder(searchSourceBuilder.toString())
// multiple index or types can be added.
.addIndex("twitter")
.addType("tweet")
.build();
SearchResult result = client.execute(search);
3.5.4.结果可以直接转为bean
SearchResult result = client.execute(search);
List<SearchResult.Hit<Article, Void>> hits = result.getHits(Article.class);
// or
List<Article> articles = result.getSourceAsObjectList(Article.class);
3.6.获取documents
Get get = new Get.Builder("twitter", "1").type("tweet").build();
JestResult result = client.execute(get);
Article article = result.getSourceAsObject(Article.class);
3.7.更新documents
String script = "{\n" +
" \"script\" : \"ctx._source.tags += tag\",\n" +
" \"params\" : {\n" +
" \"tag\" : \"blue\"\n" +
" }\n" +
"}";
client.execute(new Update.Builder(script).index("twitter").type("tweet").id("1").build());
3.8.删除document
client.execute(new Delete.Builder("1")
.index("twitter")
.type("tweet")
.build());
3.9.bulk api批量操作
3.9.1.单条数据
Bulk bulk = new Bulk.Builder()
.defaultIndex("twitter")
.defaultType("tweet")
.addAction(new Index.Builder(article1).build())
.addAction(new Index.Builder(article2).build())
.addAction(new Delete.Builder("1").index("twitter").type("tweet").build())
.build();
client.execute(bulk);
3.9.2.多条数据
String article1 = "tweet1";
String article2 = "tweet2";
Bulk bulk = new Bulk.Builder()
.defaultIndex("twitter")
.defaultType("tweet")
.addAction(Arrays.asList(
new Index.Builder(article1).build(),
new Index.Builder(article2).build()))
.build();
client.execute(bulk);
3.10.设置请求参数
ES可以将路由、版本、操作类型等属性通过请求参数的方式设置,如设置refresh
属性,如要设置枚举中没有的属性,可以直接填字符串。
Index index = new Index.Builder("{\"user\":\"kimchy\"}")
.index("cvbank")
.type("candidate")
.id("1")
.setParameter(Parameters.REFRESH, true),
.build();
client.execute(index);
3.11.jest支持异步操作
client.executeAsync(action,new JestResultHandler<JestResult>() {
@Override
public void completed(JestResult result) {
... do process result ....
}
@Override
public void failed(Exception ex) {
... catch exception ...
}
});