ES-Java-API练习
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.3.x</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
resource/es.json
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "text"
},
"body": {
"type": "text",
"analyzer": "ik_max_word"
},
"tags": {
"type": "keyword"
},
"published_on": {
"type": "keyword"
},
"comments": {
"type": "nested",
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"comment": {
"type": "text",
"analyzer": "ik_max_word"
},
"age": {
"type": "short"
},
"rating": {
"type": "short"
},
"commented_on": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
}
//实体
@Data
@Accessors(chain = true)
public class Blog {
private Long id;
private String title;
private String body;
private List<String> tags;
private Date publishedOn;
private List<Comment> comments;
}
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class Comment {
private Long id;
private String name;
private Integer age;
/**
* 评分
*/
private Integer rating;
/**
* 评语
*/
private String comment;
/**
* 评论时间
*/
private Date commentedOn;
}
1、索引的基本操作
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class IndexTest {
@Resource
private RestHighLevelClient restHighLevelClient;
private static String settings;
private static String mappings;
static {
InputStream is = IndexTest.class.getClassLoader().getResourceAsStream("es.json");
try {
String esJson = IOUtils.toString(is, StandardCharsets.UTF_8);
JSONObject jsonObject = JSON.parseObject(esJson);
settings = jsonObject.getString("settings");
mappings = jsonObject.getString("mappings");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建索引并指定mapping
* @throws IOException
*/
@Test
public void createIndex() throws IOException {
// 创建索引请求,并指定索引名称
CreateIndexRequest indexRequest = new CreateIndexRequest("blogs");
indexRequest.settings(settings, XContentType.JSON);
indexRequest.mapping(mappings, XContentType.JSON);
CreateIndexResponse response = restHighLevelClient.indices().create(indexRequest, RequestOptions.DEFAULT);
System.out.println("isAcknowledged:" + response.isAcknowledged());
}
/**
* 删除索引
* @throws IOException
*/
@Test
public void deleteIndex() throws IOException {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("blogs");
AcknowledgedResponse response = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println("isAcknowledged:" + response.isAcknowledged());
}
/**
* 查询索引的信息
* @throws IOException
*/
@Test
public void findIndex() throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest("blogs");
GetIndexResponse response = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
Map<String, Settings> settings = response.getSettings();
Map<String, List<AliasMetaData>> aliases = response.getAliases();
Map<String, MappingMetaData> mappings = response.getMappings();
System.out.println("aliases:" + aliases);
System.out.println("settings:" + settings);
System.out.println("mappings:" + JSON.toJSONString(mappings));
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}
2、文档的基本操作
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class DocumentTest {
@Resource
private RestHighLevelClient restHighLevelClient;
public Blog getOneBlog(){
return new Blog().setId(1L)
.setTitle("Invest Money")
.setBody("Please start investing money as soon...")
.setTags(Lists.newArrayList("money", "invest"))
.setPublishedOn(new Date())
.setComments(Lists.newArrayList(
new Comment().setId(1L).setName("William").setAge(34).setRating(8).setComment("Nice article..").setCommentedOn(new Date()),
new Comment().setId(2L).setName("John").setAge(38).setRating(9).setComment("I started investing after reading this.").setCommentedOn(new Date()),
new Comment().setId(3L).setName("Smith").setAge(33).setRating(7).setComment("Very good post").setCommentedOn(new Date()))
);
}
public Blog getUpdateOneBlog(){
return new Blog().setId(1L)
.setTitle("Invest Money222333")
.setBody("");
}
public List<Blog> getBlogList(){
Blog b1 = new Blog().setId(1L)
.setTitle("Invest Money")
.setBody("Please start investing money as soon...")
.setTags(Lists.newArrayList("money", "invest"))
.setPublishedOn(new Date())
.setComments(Lists.newArrayList(
new Comment().setId(1L).setName("William").setAge(34).setRating(8).setComment("Nice article..").setCommentedOn(new Date()),
new Comment().setId(2L).setName("John").setAge(38).setRating(9).setComment("I started investing after reading this.").setCommentedOn(new Date()),
new Comment().setId(3L).setName("Smith").setAge(33).setRating(7).setComment("Very good post").setCommentedOn(new Date()))
);
Blog b2 = new Blog().setId(2L)
.setTitle("Hero")
.setBody("Hero test body...")
.setTags(Lists.newArrayList("Heros", "happy"))
.setPublishedOn(new Date())
.setComments(Lists.newArrayList(
new Comment().setId(1L).setName("steve").setAge(24).setRating(18).setComment("Nice article..").setCommentedOn(new Date()))
);
return Lists.newArrayList(b1, b2);
}
public List<Blog> getUpdateBlogList(){
Blog b1 = new Blog().setId(1L)
.setTitle("Invest Money33333");
Blog b2 = new Blog().setId(2L)
.setTitle("Hero3333");
return Lists.newArrayList(b1, b2);
}
/**
* 创建一个文档
* @throws IOException
*/
@Test
public void createDocument() throws IOException {
Blog blog = getOneBlog();
IndexRequest indexRequest = new IndexRequest("blogs").id(blog.getId().toString())
.source(JSON.toJSONString(blog), XContentType.JSON);
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("result:" + response.getResult());
}
/**
* 批量创建文档
* @throws IOException
*/
@Test
public void batchCreateDocument() throws IOException {
BulkRequest bulkRequest = new BulkRequest("blogs");
for (Blog blog : getBlogList()) {
bulkRequest.add(new IndexRequest().id(blog.getId().toString()).source(JSON.toJSONString(blog), XContentType.JSON));
}
BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
for (BulkItemResponse item : response.getItems()) {
System.out.println("result:" + item.getResponse().getResult());
}
}
/**
*
* 根据查询一个文档
* @throws IOException
*/
@Test
public void findOneDocument() throws IOException {
GetRequest getRequest = new GetRequest("blogs").id("1");
GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
String source = response.getSourceAsString();
Blog blog = JSON.parseObject(source, Blog.class);
System.out.println(JSON.toJSONString(blog));
}
@Test
public void batchFindDocument() throws IOException {
MultiGetRequest request = new MultiGetRequest()
.add(new MultiGetRequest.Item("blogs", "1"))
.add(new MultiGetRequest.Item("blogs", "2"))
.add(new MultiGetRequest.Item("blogs", "3"));
MultiGetResponse responses = restHighLevelClient.mget(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(responses));
responses.iterator().forEachRemaining(response -> {
System.out.println(response.getResponse().getSource());
});
}
/**
* 更新一个对象,部分更新
* @throws IOException
*/
@Test
public void updateOneDocument() throws IOException {
Blog updateOneBlog = getUpdateOneBlog();
UpdateRequest updateRequest = new UpdateRequest("blogs", updateOneBlog.getId().toString());
updateRequest.doc(JSON.toJSONString(updateOneBlog), XContentType.JSON);
updateRequest.docAsUpsert(true);
UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println("result:" + response.getResult());
}
/**
* 批量更新对象,部分更新
*/
@Test
public void batchUpdateDocument() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
getUpdateBlogList().forEach(blog -> {
UpdateRequest updateRequest = new UpdateRequest("blogs", blog.getId().toString());
updateRequest.doc(JSON.toJSONString(blog), XContentType.JSON);
bulkRequest.add(updateRequest);
});
BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
for (BulkItemResponse item : response.getItems()) {
System.out.println(item.getId() + ":" + item.getResponse().getResult());
}
}
/**
* 删除一个文档
*/
@Test
public void deleteOneDocument() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("blogs");
deleteRequest.id("1");
DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println("result:" + response.getResult());
}
/**
* 批量删除文档
*/
@Test
public void batchDeleteDocument() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest
.add(new DeleteRequest("blogs").id("2"))
.add(new DeleteRequest("blogs").id("1"));
BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
for (BulkItemResponse item : response.getItems()) {
System.out.println(item.getId() + ":" + item.getResponse().getResult());
}
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}
3、ES高级查询
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class QueryDSLTest {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
public void queryTest() throws IOException {
// 1.查询全部
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.matchAllQuery());
// 2.查询全部,但是只返回部分字段
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.matchAllQuery())
// .fetchSource(new String[]{"id", "title"}, null);
// 3.关键词查询term
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.termQuery("title", "hero"));
// 4.范围查询range
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.rangeQuery("id").gte(1).lte(2));
// 5.前缀查询prefix
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.prefixQuery("title", "h"));
// 6.通配符查询wildcard
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.wildcardQuery("title", "*Money*"));
// 7.多id查询
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.idsQuery().addIds("1", "2"));
// 8.模糊查询fuzzy
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.fuzzyQuery("title", "Money"));
// 9.bool查询
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .must(QueryBuilders.termQuery("title", "hero"))
// .must(QueryBuilders.idsQuery().addIds("2"))
// );
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .mustNot(QueryBuilders.termQuery("title", "hero"))
// );
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .should(QueryBuilders.termQuery("title", "hero"))
// .should(QueryBuilders.idsQuery().addIds("1"))
// );
// 10.多字段查询multi_match
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.multiMatchQuery("test", "title", "body"));
// 11.默认字段分词查询
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.queryStringQuery("hero").defaultField("title"));
// 12.高亮查询hightlight
// HighlightBuilder highlightBuilder = new HighlightBuilder()
// .field("body").field("title")
// .requireFieldMatch(false)
// .preTags("<span style='color:red'>")
// .postTags("</span>");
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.termQuery("body", "hero"))
// .highlighter(highlightBuilder);
// 13.分页查询from、size
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.matchAllQuery())
// .from(1)
// .size(1);
// 14.排序sort
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(QueryBuilders.matchAllQuery())
.sort("id", SortOrder.DESC);
query(sourceBuilder);
}
/**
* 查询
* @throws IOException
*/
public void query(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long hitValue = response.getHits().getTotalHits().value;
System.out.println("查询条数:" + hitValue);
for (SearchHit hit : response.getHits().getHits()) {
// 查询结果
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 高亮处理
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
highlightFields.forEach((key, field) -> {
Object o = sourceAsMap.get(key);
if(o != null){
sourceAsMap.put(key, field.getFragments()[0].string());
}
});
String json = JSON.toJSONString(sourceAsMap);
Blog blog = JSON.parseObject(json, Blog.class);
System.out.println(blog);
}
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}
4、ES过滤查询
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class FilterQueryTest {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
public void queryTest() throws IOException {
// 1.term过滤器
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .filter(QueryBuilders.termQuery("title", "hero"))
// .must(QueryBuilders.termQuery("body", "test")));
// 2.terms过滤器
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .filter(QueryBuilders.termsQuery("title", "hero", "money")));
// 3.range过滤器
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .filter(QueryBuilders.rangeQuery("id").gte("1").lte("1")));
// 4.exists过滤器
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .filter(QueryBuilders.existsQuery("title")));
// 5.ids过滤器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.filter(QueryBuilders.idsQuery().addIds("1").addIds("2")));
query(sourceBuilder);
}
/**
* 查询
* @throws IOException
*/
public void query(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long hitValue = response.getHits().getTotalHits().value;
System.out.println("查询条数:" + hitValue);
for (SearchHit hit : response.getHits().getHits()) {
// 查询结果
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 高亮处理
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
highlightFields.forEach((key, field) -> {
Object o = sourceAsMap.get(key);
if(o != null){
sourceAsMap.put(key, field.getFragments()[0].string());
}
});
String json = JSON.toJSONString(sourceAsMap);
Blog blog = JSON.parseObject(json, Blog.class);
System.out.println(blog);
}
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}
5、ES聚合查询
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class AggregationTest {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
public void queryTest() throws IOException {
// 1.分组聚合
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .aggregation(AggregationBuilders.terms("time_group").field("publishedOn"))
// .size(0);
// query(sourceBuilder);
// 2.最大值
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .aggregation(AggregationBuilders.max("id_group").field("id"))
// .size(0);
// query2(sourceBuilder);
// 3.最小值
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .aggregation(AggregationBuilders.min("id_group").field("id"))
// .size(0);
// query3(sourceBuilder);
// 4.平均值
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .aggregation(AggregationBuilders.avg("id_group").field("id"))
// .size(0);
// query4(sourceBuilder);
// 5.求和
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.aggregation(AggregationBuilders.sum("id_group").field("id"))
.size(0);
query5(sourceBuilder);
}
/**
* 分组聚合查询
* @throws IOException
*/
public void query(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedLongTerms aggregation = aggregations.get("time_group");
List<? extends Terms.Bucket> buckets = aggregation.getBuckets();
for (Terms.Bucket bucket : buckets) {
System.out.println(bucket.getKey() + ":" + bucket.getDocCount());
}
}
/**
* 求最大值
* @param sourceBuilder
* @throws IOException
*/
public void query2(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedMax max = aggregations.get("id_group");
System.out.println(max.getValue());
}
/**
* 求最小值
* @param sourceBuilder
* @throws IOException
*/
public void query3(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedMin min = aggregations.get("id_group");
System.out.println(min.getValue());
}
/**
* 求平均值
* @param sourceBuilder
* @throws IOException
*/
public void query4(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedAvg avg = aggregations.get("id_group");
System.out.println(avg.getValue());
}
/**
* 求和
* @param sourceBuilder
* @throws IOException
*/
public void query5(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedSum sum = aggregations.get("id_group");
System.out.println(sum.getValue());
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}
6、Nested嵌套查询
@SpringBootTest(classes = ESApplication.class)
@RunWith(SpringRunner.class)
public class NestedTest {
@Resource
private RestHighLevelClient restHighLevelClient;
@Test
public void queryTest() throws IOException {
// 1.Nested查询
// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
// .query(QueryBuilders.boolQuery()
// .must(QueryBuilders.nestedQuery("comments", QueryBuilders.boolQuery()
// .must(QueryBuilders.matchQuery("comments.name", "John"))
// .must(QueryBuilders.matchQuery("comments.age", 38)),ScoreMode.None)));
//
// query(sourceBuilder);
// 2.nested聚合查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.aggregation(AggregationBuilders.nested("comm_aggs", "comments")
.subAggregation(AggregationBuilders.min("min_age").field("comments.age")))
.size(0);
query2(sourceBuilder);
}
public void query2(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
ParsedNested aggregation = aggregations.get("comm_aggs");
long docCount = aggregation.getDocCount();
ParsedMin age = aggregation.getAggregations().get("min_age");
System.out.println("doc_count: " + docCount + "," + "min_age:" + age.getValue());
}
/**
* 查询
* @throws IOException
*/
public void query(SearchSourceBuilder sourceBuilder) throws IOException {
SearchRequest searchRequest = new SearchRequest("blogs");
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
long hitValue = response.getHits().getTotalHits().value;
System.out.println("查询条数:" + hitValue);
for (SearchHit hit : response.getHits().getHits()) {
// 查询结果
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 高亮处理
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
highlightFields.forEach((key, field) -> {
Object o = sourceAsMap.get(key);
if(o != null){
sourceAsMap.put(key, field.getFragments()[0].string());
}
});
String json = JSON.toJSONString(sourceAsMap);
Blog blog = JSON.parseObject(json, Blog.class);
System.out.println(blog);
}
}
@After
public void after() throws IOException {
restHighLevelClient.close();
}
}