ElasticSearch(ES) 是开源(apache 2 授权)、分布式、REST风格、搜索引擎基于Lucene的实现。
Jest是一个为ES操作Java Http Rest 的客户端,及使用它来捕获、存储以及操作数据。
Jest提供JavaAPI,可以很好的处理Java对象序列。通过Jest,可以获取普通的Java对象并在ES中为它们建立索引。然后使用ES的搜索API,将您的返回的对象转换Java对象。
可以通过Andrew Glover来阅读ES和Jest
安装说明
Jest Maven 托管在 Sonatype.
配置pom.xml 文件
1
2
3
4
5
6
7
8
9
10
11
|
<
repositories
>
.
.
<
repository
>
<
id
>sonatype</
id
>
<
name
>Sonatype Groups</
name
>
<
url
>https://oss.sonatype.org/content/groups/public/</
url
>
</
repository
>
.
.
</
repositories
>
|
添加依赖
1
2
3
4
5
|
<
dependency
>
<
groupId
>io.searchbox</
groupId
>
<
artifactId
>jest</
artifactId
>
<
version
>0.0.3</
version
>
</
dependency
>
|
更新日志 changelog
Jest 有一个简单的实例,请看这里 --->
使用Jest之前要需要一个JestClient
1
2
3
4
5
6
7
8
9
10
11
|
// Configuration
ClientConfig clientConfig =
new
ClientConfig();
LinkedHashSet<String> servers =
new
LinkedHashSet<String>();
servers.add(
"http://localhost:9200"
);
clientConfig.getProperties().put(ClientConstants.SERVER_LIST, servers);
clientConfig.getProperties().put(ClientConstants.IS_MULTI_THREADED,
true
);
// Construct a new Jest client according to configuration via factory
JestClientFactory factory =
new
JestClientFactory();
factory.setClientConfig(clientConfig);
JestClient client = factory.getObject();
|
JestClient使用单例模式,构造器是私有。
开始创建索引
通过Jest创建Index是一件很轻松的事
1
|
client.execute(
new
CreateIndex(
"articles"
));
|
设置ES参数,可以通过JSON完成
1
2
3
4
5
6
|
String settings =
"\"settings\" : {\n"
+
" \"number_of_shards\" : 5,\n"
+
" \"number_of_replicas\" : 1\n"
+
" }\n"
;
client.execute(
new
CreateIndex(
"articles"
), settings)
|
或者通过SetingsBuilder,添加ES依赖设置API
1
2
3
4
5
6
7
8
9
|
import
org.elasticsearch.common.settings.ImmutableSettings;
.
.
ImmutableSettings.Builder settingsBuilder = ImmutableSettings.settingsBuilder();
settings.put(
"number_of_shards"
,
5
);
settings.put(
"number_of_replicas"
,
1
);
client.execute(
new
CreateIndex(
"articles"
), settingsBuilder.build().getAsMap());
|
索引文档
ES请求索引数据JSON格式,通过Jest的几种方法创建文档索引
1.JSON 字符串
1
|
String source =
"{\"user\":\"kimchy\"}"
;
|
2.ES JSONBuilder
1
2
3
4
5
6
|
String source = jsonBuilder()
.startObject()
.field(
"user"
,
"kimchy"
)
.field(
"postDate"
,
"date"
)
.field(
"message"
,
"trying out Elastic Search"
)
.endObject().string();
|
3.Map
1
2
|
Map<String, String> source =
new
LinkedHashMap<String,String>()
source.put(
"user"
,
"kimchy"
);
|
4.POJO
1
2
3
|
Article source =
new
Article();
source.setAuthor(
"John Ronald Reuel Tolkien"
);
source.setContent(
"The Lord of the Rings is an epic high fantasy novel"
);
|
指定索引数据生成索引 为twitter index with type tweet
1
2
|
Index index =
new
Index.Builder(source).index(
"twitter"
).type(
"tweet"
).build();
client.execute(index);
|
可以明确指定索引Id
1
2
|
Index index =
new
Index.Builder(source).index(
"twitter"
).type(
"tweet"
).id(
"1"
).build();
client.execute(index);
|
也可以通过Jest注解的方式指定索引Id
1
2
3
4
5
6
|
class
Article {
@JestId
private
Long documentId;
}
|
如果JestId 是null,则有ES自动生成Id。
搜索文档
通过Json 字符串搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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(query);
// multiple index or types can be added.
search.addIndex(
"twitter"
);
search.addType(
"tweet"
);
JestResult result = client.execute(search);
|
使用SearchSourceBuilder
1
2
3
4
5
6
7
8
|
SearchSourceBuilder searchSourceBuilder =
new
SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery(
"user"
,
"kimchy"
));
Search search =
new
Search(searchSourceBuilder.toString());
search.addIndex(
"twitter"
);
search.addType(
"tweet"
);
JestResult result = client.execute(search);
|
结果转换成对象
1
2
|
JestResult result = client.execute(search);
List<Article> articles = result.getSourceAsObjectList(Article.
class
);
|
如果要阅读复杂的查询,请这里走-->
获取索引文档
1
2
3
|
Get get =
new
Get.Builder(
"1"
).index(
"twitter"
).type(
"tweet"
).build();
JestResult result = client.execute(get);
|
结果转换成对象
1
2
3
4
5
|
Get get =
new
Get.Builder(
"1"
).index(
"twitter"
).type(
"tweet"
).build();
JestResult result = client.execute(get);
Article article = result.getSourceAsObject(Article.
class
);
|
更新索引文档
1
2
3
4
5
6
7
8
|
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());
|
删除文档
1
|
client.execute(
new
Delete.Builder(
"1"
).index(
"twitter"
).type(
"tweet"
).build());
|
批量操作
通过API批量操作 index/delete 操作,可以大大增加索引速度。
1
2
3
4
5
6
7
|
Bulk bulk =
new
Bulk(
"twitter"
,
"tweet"
);
bulk.addIndex(
new
Index.Builder(article1).build());
bulk.addIndex(
new
Index.Builder(article2).build());
bulk.addDelete(
new
Delete.Builder(
"1"
).build());
client.execute(bulk);
|
集合批量操作
1
2
3
4
5
|
Bulk bulk =
new
Bulk(
"twitter"
,
"tweet"
);
Article article1 =
new
Article(
"tweet1"
);
Article article2 =
new
Article(
"tweet1"
);
bulk.addIndexList(Arrays.asList(article1, article2););
client.execute(bulk);
|
设置参数
ElasticSearch要求参数来设置属性,如 routing, versioning 操作类型等
比如设置“refresh” 为 “true”
1
2
3
|
Index index =
new
Index.Builder(
"{\"user\":\"kimchy\"}"
).index(
"cvbank"
).type(
"candidate"
).id(
"1"
).build();
index.addParameter(Parameters.REFRESH,
true
);
client.execute(index);
|
同步操作
Jest http Client 支持 blocking IO asynchronously.
使用Jest 同步操作实例
1
2
3
4
5
6
7
8
9
10
|
client.executeAsync(action,
new
JestResultHandler<JestResult>() {
@Override
public
void
completed(JestResult result) {
...
do
process result ....
}
@Override
public
void
failed(Exception ex) {
...
catch
exception ...
}
});
|
配置在同一网段内发下其它节点设置
1
2
3
4
|
//enable host discovery
clientConfig.getProperties().put(ClientConstants.DISCOVERY_ENABLED,
true
);
//boolean
clientConfig.getProperties().put(ClientConstants.DISCOVERY_FREQUENCY, 1l);
//long
clientConfig.getProperties().put(ClientConstants.DISCOVERY_FREQUENCY_TIMEUNIT, TimeUnit.MINUTES);
|
http://my.oschina.net/shking/blog/133366