Elasticsearch的Java API操作
文章目录
pom.xml
一.创建maven工程
<repositories>
<!--<repository>-->
<!--<id>elastic.co</id>-->
<!--<url>https://artifacts.elastic.co/maven</url>-->
<!--</repository>-->
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<dependencies>
<!--解析excel文件-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-mr1-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.2.0-cdh5.14.0</version>
</dependency>
<!--=============================================================================-->
<!-- 这个jar包需要去es官网下载 -->
<!--<dependency>-->
<!--<groupId>org.elasticsearch.plugin</groupId>-->
<!--<artifactId>x-pack-sql-jdbc</artifactId>-->
<!--<version>6.7.0</version>-->
<!--</dependency>-->
<!--=============================================================================-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
javaBean
import java.io.Serializable;
public class Person implements Serializable {
private Integer id;
private String name ;
private Integer age;
private Integer sex;
private String address;
private String phone;
private String email;
private String say;
public Person() {
}
public Person(Integer id, String name, Integer age, Integer sex, String address, String phone, String email,String say) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
this.phone = phone;
this.email = email;
this.say = say;
}
public String getSay() {
return say;
}
public void setSay(String say) {
this.say = say;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
二.增删改索引
(一)添加索引
1.以json字符串形式添加索引
2.使用map来构建索引
3.使用XContentFactory添加索引
4.将javaBean对象添加到索引库
5.批量添加索引
(二)更新索引
(三)删除索引
(四)删除索引库
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
/**
* User: Devin Kim
* Date: 2019/12/12 17:03
* Description:增删改索引
*/
public class EsIndexOperate {
private TransportClient transportClient;
@BeforeTest
public void initClient() throws UnknownHostException {
Settings settings = Settings.builder().put("cluster.name", "myes").build();
TransportAddress node01 = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress node02 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress node03 = new TransportAddress(InetAddress.getByName("node03"), 9300);
transportClient = new PreBuiltTransportClient(settings)
.addTransportAddress(node01)
.addTransportAddress(node02)
.addTransportAddress(node03);
}
@AfterTest
public void close(){
transportClient.close();
}
@Test//一.以json字符串形式添加索引
public void addIndex01(){
String json = "{" +
"\"user\":\"Devin Kim\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"traveling out Elasticsearch\"" +
"}";
IndexRequestBuilder indexRequestBuilder = transportClient.prepareIndex("myindex01", "article01", "1")
.setSource(json, XContentType.JSON);
indexRequestBuilder.get();//以http请求的方式发送去执行
}
@Test//二、使用map来构建索引
public void addIndex02(){
HashMap<String,String> map = new HashMap<>();
map.put("name","Jack");
map.put("age","34");
map.put("address","月球人");
transportClient
.prepareIndex("myindex01","article01","2")
.setSource(map)
.get();
}
@Test//三、使用XContentFactory添加索引
public void addIndex03() throws IOException {
XContentBuilder xContentBuilder = new XContentFactory()
.jsonBuilder()
.startObject()
.field("name", "张三")
.field("age", 18)
.field("sex", "0")
.field("address", "北京")
.endObject();
transportClient.prepareIndex("myindex01", "article01", "3")
.setSource(xContentBuilder)
.get();
}
@Test//四、将javaBean对象添加到索引库
public void addIndex04(){
Person person = new Person();
person.setAddress("上海");
person.setAge(28);
person.setEmail("wangwu@163.com");
String jsonStr = JSONObject.toJSONString(person);
transportClient.prepareIndex("myindex01","article01","4")
.setSource(jsonStr,XContentType.JSON)
.get();
}
@Test//五.批量添加索引
public void addIndexBulk(){
Person person = new Person();
person.setEmail("wangwu@qq.com");
Person person1 = new Person();
person1.setName("赵六");
IndexRequestBuilder indexRequestBuilder = transportClient.prepareIndex("myindex01", "article01", "5")
.setSource(JSONObject.toJSONString(person), XContentType.JSON);
IndexRequestBuilder indexRequestBuilder1 = transportClient.prepareIndex("myindex01", "article01", "6")
.setSource(JSONObject.toJSONString(person1), XContentType.JSON);
transportClient.prepareBulk()
.add(indexRequestBuilder)
.add(indexRequestBuilder1)
.get();
}
@Test//更新索引
public void updateIndex(){
Person person = new Person();
person.setEmail("laoli@google.com");
person.setAge(28);
person.setName("老李");
transportClient.prepareUpdate("myindex01","article01","6")
.setDoc(JSONObject.toJSONString(person), XContentType.JSON)
.get();
}
@Test//删除索引
public void deleteIndex(){
transportClient.prepareDelete("myindex01","article01","6")
.get();
}
@Test//删除索引库
public void deleteWholeIndex(){
transportClient.admin()
.indices()
.prepareDelete("myindex01")
.execute()
.actionGet();
}
}
三.查询索引
(一)普通API查询
1.查询索引库中所有数据
2.范围查询
3.词条查询
4.通配符查询
5.条件组合查询
6.分页查询
7.高亮显示
初始化一批数据到索引库当中去准备做查询使用, 注意这里初始化的时候,需要给我们的数据设置分词属性。
import com.alibaba.fastjson.JSONObject;
import com.devinkim.utils.Person;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import java.io.IOException;
import java.net.InetAddress;
public class CreateIndexBatch {
public static void main(String[] args) throws IOException {
Settings settings = Settings.builder().put("cluster.name", "myes").build();
TransportAddress node01 = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress node02 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress node03 = new TransportAddress(InetAddress.getByName("node03"), 9300);
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(node01)
.addTransportAddress(node02)
.addTransportAddress(node03);
//创建映射 定义mappings里面字段类型以及分词,存储,索引特性
/* 拓展:
keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤
(比如查找已发布博客中status属性为published的文章)、排序、聚合。
keyword类型的字段只能通过精确值搜索到。
*/
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
// .startObject("m_id").field("type","keyword").endObject()
.startObject("id").field("type", "integer").endObject()
.startObject("name").field("type", "text").field("analyzer", "ik_max_word").endObject()
.startObject("age").field("type", "integer").endObject()
.startObject("sex").field("type", "text").field("analyzer", "ik_max_word").endObject()
.startObject("address").field("type", "text").field("analyzer", "ik_max_word").endObject()
.startObject("phone").field("type", "text").endObject()
.startObject("email").field("type", "text").endObject()
.startObject("say").field("type", "text").field("analyzer", "ik_max_word").endObject()
.endObject()
.endObject();
//pois:索引名 cxyword:类型名(可以自己定义)
PutMappingRequest putmap = Requests.putMappingRequest("indexsearch").type("mysearch").source(mapping);
//创建索引
client.admin().indices().prepareCreate("indexsearch").execute().actionGet();
//为索引添加映射
client.admin().indices().putMapping(putmap).actionGet();
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
Person lujunyi = new Person(2, "玉麒麟卢俊义", 28, 1, "水泊梁山", "17666666666", "lujunyi@devinkim.com","hello world今天天气还不错");
Person wuyong = new Person(3, "智多星吴用", 45, 1, "水泊梁山", "17666666666", "wuyong@devinkim.com","行走四方,抱打不平");
Person gongsunsheng = new Person(4, "入云龙公孙胜", 30, 1, "水泊梁山", "17666666666", "gongsunsheng@devinkim.com","走一个");
Person guansheng = new Person(5, "大刀关胜", 42, 1, "水泊梁山", "17666666666", "wusong@devinkim.com","我的大刀已经饥渴难耐");
Person linchong = new Person(6, "豹子头林冲", 18, 1, "水泊梁山", "17666666666", "linchong@devinkim.com","梁山好汉");
Person qinming = new Person(7, "霹雳火秦明", 28, 1, "水泊梁山", "17666666666", "qinming@devinkim.com","不太了解");
Person huyanzhuo = new Person(8, "双鞭呼延灼", 25, 1, "水泊梁山", "17666666666", "huyanzhuo@devinkim.com","不是很熟悉");
Person huarong = new Person(9, "小李广花荣", 50, 1, "水泊梁山", "17666666666", "huarong@devinkim.com","打酱油的");
Person chaijin = new Person(10, "小旋风柴进", 32, 1, "水泊梁山", "17666666666", "chaijin@devinkim.com","吓唬人的");
Person zhisheng = new Person(13, "花和尚鲁智深", 15, 1, "水泊梁山", "17666666666", "luzhisheng@devinkim.com","倒拔杨垂柳");
Person wusong = new Person(14, "行者武松", 28, 1, "水泊梁山", "17666666666", "wusong@devinkim.com","二营长。。。。。。");
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "1")
.setSource(JSONObject.toJSONString(lujunyi), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "2")
.setSource(JSONObject.toJSONString(wuyong), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "3")
.setSource(JSONObject.toJSONString(gongsunsheng), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "4")
.setSource(JSONObject.toJSONString(guansheng), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "5")
.setSource(JSONObject.toJSONString(linchong), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "6")
.setSource(JSONObject.toJSONString(qinming), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "7")
.setSource(JSONObject.toJSONString(huyanzhuo), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "8")
.setSource(JSONObject.toJSONString(huarong), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "9")
.setSource(JSONObject.toJSONString(chaijin), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "10")
.setSource(JSONObject.toJSONString(zhisheng), XContentType.JSON)
);
bulkRequestBuilder.add(client.prepareIndex("indexsearch", "mysearch", "11")
.setSource(JSONObject.toJSONString(wusong), XContentType.JSON)
);
bulkRequestBuilder.get();
client.close();
}
}
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* User: Devin Kim
* Date: 2019/12/12 17:37
* Description:
*/
public class EsQueryOperate {
private TransportClient transportClient;
@BeforeTest
public void initClient() throws UnknownHostException {
Settings settings = Settings.builder().put("cluster.name", "myes").build();
TransportAddress node01 = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress node02 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress node03 = new TransportAddress(InetAddress.getByName("node03"), 9300);
transportClient = new PreBuiltTransportClient(settings)
.addTransportAddress(node01)
.addTransportAddress(node02)
.addTransportAddress(node03);
}
@AfterTest
public void close(){
transportClient.close();
}
@Test//查询索引库中所有数据
public void queryAll(){
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
//返回值SearchResponse对象封装了我们所有的查询结果
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(matchAllQueryBuilder)//setQuery 设置我们的查询条件
.get();
//打印返回值
System.out.println(searchResponse);
printResult(searchResponse);
}
public void printResult(SearchResponse searchResponse){
SearchHits hits = searchResponse.getHits();
SearchHit[] hit = hits.getHits();
for (SearchHit searchHit : hit) {
String sourceAsString = searchHit.getSourceAsString();
System.out.println(sourceAsString);
}
}
@Test//查询18~28岁的人
public void rangQuery(){
RangeQueryBuilder ageRangeQuery = QueryBuilders.rangeQuery("age").gt(18).lte(28);
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(ageRangeQuery)
.get();
printResult(searchResponse);
}
@Test//词条查询
public void termQuery(){
//使用词条查询的前提,被查询的字段进行分词设计
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("say", "营长");
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(termQueryBuilder)
.get();
printResult(searchResponse);
}
@Test//通配符查询
public void wildCardQuery(){
// ? 表示匹配一个字符
// * 表示匹配任意多个字符
WildcardQueryBuilder wildCardQueryBuilder = QueryBuilders.wildcardQuery("say", "hell?");
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(wildCardQueryBuilder)
.get();
printResult(searchResponse);
}
@Test//条件组合查询
public void booleanQuery(){
//查询年龄是18到28范围内且性别是男性的,或者id范围在10到13范围内的
RangeQueryBuilder ageRangeQuery = QueryBuilders.rangeQuery("age").gte(18).lte(28);
TermQueryBuilder sexTermQuery = QueryBuilders.termQuery("sex", 1);
RangeQueryBuilder idRangeQuery = QueryBuilders.rangeQuery("id").gte(10).lte(13);
BoolQueryBuilder should = QueryBuilders.boolQuery()
.should(QueryBuilders.boolQuery().must(ageRangeQuery).must(sexTermQuery))
.should(idRangeQuery);
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(should)
.get();
printResult(searchResponse);
}
@Test//分页查询
public void pageQuery(){
int pageSize = 5;
int pageNum = 3;
int startNum = (pageNum - 1) * pageSize;
SearchResponse searchResponse = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setFrom(startNum).setSize(pageSize)
.addSort("id", SortOrder.ASC)
.setQuery(QueryBuilders.matchAllQuery())
.get();
printResult(searchResponse);
}
@Test//高亮显示
public void highLighter(){
//使用词条查询 查询say这个字段,对hello关键词进行 高亮显示
SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("indexsearch")
.setTypes("mysearch")
.setQuery(QueryBuilders.termQuery("say", "hello"));
HighlightBuilder highlightBuilder = new HighlightBuilder()
.field("say")
.preTags("<font color=red>")
.postTags("</font>");
SearchResponse searchResponse = searchRequestBuilder.highlighter(highlightBuilder).get();
printResult(searchResponse);
//获取高亮字段
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits) {
Text[] says = hit.getHighlightFields().get("say").getFragments();
for (Text say : says) {
System.out.println(say);
}
}
}
}
(二)高级API查询-分组|聚合|排序
初始化一批数据到索引库当中去准备做查询使用, 注意这里初始化的时候,需要给我们的数据设置分词属性。
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import java.io.IOException;
import java.net.InetAddress;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
* User: Devin Kim
* Date: 2019/12/12 16:48
* Description:
*/
public class CreatePlayerIndex {
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
//获取settings并设置集群名字,要与集群elasticsearch.yml配置文件中保持一致
Settings settings = Settings.builder().put("cluster.name", "myes").build();
//获取客户端对象,javaAPI操作es时,使用9300端口号
TransportAddress node01 = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress node02 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress node03 = new TransportAddress(InetAddress.getByName("node03"), 9300);
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(node01)
.addTransportAddress(node02)
.addTransportAddress(node03);
client.admin().indices().prepareCreate("player").get();
//构建json的数据格式,创建映射
XContentBuilder mappingBuilder = jsonBuilder()
.startObject()
.startObject("player")
.startObject("properties")
.startObject("name").field("type","text").field("index", "true").field("fielddata","true").endObject()
.startObject("age").field("type","integer").endObject()
.startObject("salary").field("type","integer").endObject()
.startObject("team").field("type","text").field("index", "true").field("fielddata","true").endObject()
.startObject("position").field("type","text").field("index", "true").field("fielddata","true").endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest request = Requests.putMappingRequest("player")
.type("player")
.source(mappingBuilder);
client.admin().indices().putMapping(request).get();
//批量添加数据开始
BulkRequestBuilder bulkRequest = client.prepareBulk();
// either use client#prepare, or use Requests# to directly build index/delete requests
bulkRequest.add(client.prepareIndex("player", "player", "1")
.setSource(jsonBuilder()
.startObject()
.field("name", "郭德纲")
.field("age", 33)
.field("salary",3000)
.field("team" , "cav")
.field("position" , "sf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "2")
.setSource(jsonBuilder()
.startObject()
.field("name", "于谦")
.field("age", 25)
.field("salary",2000)
.field("team" , "cav")
.field("position" , "pg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "3")
.setSource(jsonBuilder()
.startObject()
.field("name", "岳云鹏")
.field("age", 29)
.field("salary",1000)
.field("team" , "war")
.field("position" , "pg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "4")
.setSource(jsonBuilder()
.startObject()
.field("name", "爱因斯坦")
.field("age", 21)
.field("salary",300)
.field("team" , "tim")
.field("position" , "sg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "5")
.setSource(jsonBuilder()
.startObject()
.field("name", "张云雷")
.field("age", 26)
.field("salary",2000)
.field("team" , "war")
.field("position" , "pf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "6")
.setSource(jsonBuilder()
.startObject()
.field("name", "爱迪生")
.field("age", 40)
.field("salary",1000)
.field("team" , "tim")
.field("position" , "pf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "7")
.setSource(jsonBuilder()
.startObject()
.field("name", "牛顿")
.field("age", 21)
.field("salary",500)
.field("team" , "tim")
.field("position" , "c")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "8")
.setSource(jsonBuilder()
.startObject()
.field("name", "特斯拉")
.field("age", 20)
.field("salary",500)
.field("team" , "tim")
.field("position" , "sf")
.endObject()
)
);
BulkResponse bulkResponse = bulkRequest.get();
client.close();
}
}
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.avg.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
/**
* User: Devin Kim
* Date: 2019/12/12 17:38
* Description:
*/
public class EsDifficultQueryOperate {
private TransportClient transportClient;
@BeforeTest
public void initClient() throws UnknownHostException {
Settings settings = Settings.builder().put("cluster.name", "myes").build();
TransportAddress node01 = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress node02 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress node03 = new TransportAddress(InetAddress.getByName("node03"), 9300);
transportClient = new PreBuiltTransportClient(settings)
.addTransportAddress(node01)
.addTransportAddress(node02)
.addTransportAddress(node03);
}
@AfterTest
public void close(){
transportClient.close();
}
@Test//统计每个球队当中球员的数量, SQL语句实现:select team, count(*) as player_count from player group by team;
public void countPlayerByTeam(){
//1:构建查询提交
SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("player").setTypes("player");
//2:指定聚合条件
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("team_count").field("team");
//3:将聚合条件放入查询条件中,通知get方法执行action,返回searchResponse
SearchResponse searchResponse = searchRequestBuilder.addAggregation(termsAggregationBuilder).get();
System.out.println(searchResponse);
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
Object key = bucket.getKey();
long docCount = bucket.getDocCount();
System.out.println(key+"位置下,有:"+docCount+"名球员");
}
}
}
@Test//统计每个球队中每个位置的球员数量,SQL语句实现:select team, position, count(*) as pos_count from player group by team, position;
public void teamAndPosition(){
TermsAggregationBuilder team = AggregationBuilders.terms("player_count").field("team");
TermsAggregationBuilder position = AggregationBuilders.terms("position_count").field("position");
team.subAggregation(position);
SearchResponse searchResponse = transportClient.prepareSearch("player")
.setTypes("player")
.addAggregation(team)
.get();
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
Object key = bucket.getKey();
long teamValue = bucket.getDocCount();
System.out.println(key+" 队伍下共有:"+ teamValue + "人");
Aggregation position_count = bucket.getAggregations().get("position_count");
if(position_count != null){
StringTerms positionStringTerm = (StringTerms) position_count;
List<StringTerms.Bucket> positionBuckets = positionStringTerm.getBuckets();
for (StringTerms.Bucket positionBucket : positionBuckets) {
Object positionKey = positionBucket.getKey();
long positionValue = positionBucket.getDocCount();
System.out.println("\t"+positionKey+" 位置有:"+positionValue+"人");
}
}
}
}
}
@Test//分组求每个球队当中年龄的max、min、avg,SQL语句实现:select team, max(age) as max_age from player group by team;
public void aggregateOperate(){
//先设置按球队进行分组聚合
TermsAggregationBuilder termAggregationBuilder = AggregationBuilders.terms("team_count").field("team");
//求每个球队当中年龄最大的值
//MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("max_age").field("age");
//termAggregationBuilder.subAggregation(maxAggregationBuilder);
//求每个球队当中年龄最小值
//MinAggregationBuilder minAggregationBuilder = AggregationBuilders.min("min_age").field("age");
//termAggregationBuilder.subAggregation(minAggregationBuilder);
//求每个球队当中平均年龄
AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("avg_age").field("age");
termAggregationBuilder.subAggregation(avgAggregationBuilder);
SearchResponse searchResponse = transportClient.prepareSearch("player")
.setTypes("player")
.addAggregation(termAggregationBuilder)
.get();
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
String team = (String) bucket.getKey();
Aggregation max_age = bucket.getAggregations().get("max_age");
Aggregation min_age = bucket.getAggregations().get("min_age");
Aggregation avg_age = bucket.getAggregations().get("avg_age");
System.out.println(team + max_age + min_age + avg_age);
}
}
}
@Test//计算每个球队球员的平均年龄,同时又要计算总年薪,SQL语句实现:select team, avg(age)as avg_age, sum(salary) as total_salary from player group by team;
public void avgAndSum(){
TermsAggregationBuilder team = AggregationBuilders.terms("team_group").field("team");
AvgAggregationBuilder age = AggregationBuilders.avg("avg_age").field("age");
SumAggregationBuilder salary = AggregationBuilders.sum("sum_salary").field("salary");
TermsAggregationBuilder termsAggregationBuilder = team.subAggregation(age).subAggregation(salary);
SearchResponse searchResponse = transportClient.prepareSearch("player")
.setTypes("player")
.addAggregation(termsAggregationBuilder)
.get();
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
Object teamName = bucket.getKey();
Aggregation avg_age = bucket.getAggregations().get("avg_age");
String AgeTempStr = avg_age.toString().substring(20);
String ageStr = AgeTempStr.substring(0, AgeTempStr.length() - 2);
Aggregation sum_salary = bucket.getAggregations().get("sum_salary");
String salaryTempStr = sum_salary.toString().substring(23);
String salaryStr = salaryTempStr.substring(0, salaryTempStr.length() - 2);
System.out.println(teamName+"队伍的平均年龄是:" + ageStr + "岁," +
"总年薪是:" + Double.parseDouble(salaryStr));
}
}
}
@Test//计算每个球队总年薪,并按照总年薪倒序排列,SQL语句实现:select team, sum(salary) as total_salary from player group by team order by total_salary desc
public void orderBySalary(){
TermsAggregationBuilder teamOrder = AggregationBuilders.terms("team_group")
.field("team")
.order(BucketOrder.count(true));
SumAggregationBuilder sum = AggregationBuilders.sum("sum_salary").field("salary");
teamOrder.subAggregation(sum);
SearchResponse searchResponse = transportClient.prepareSearch("player").setTypes("player")
.addAggregation(teamOrder)
.get();
//Map<String, Aggregation> stringAggregationMap = searchResponse.getAggregations().asMap();
//System.out.println(stringAggregationMap);
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
Object teamName = bucket.getKey();
Aggregation salaryAgg = bucket.getAggregations().get("sum_salary");
StringTerms salaryStringTerm = (StringTerms) salaryAgg;
for (StringTerms.Bucket salaryBucket : salaryStringTerm.getBuckets()) {
long docCount = salaryBucket.getDocCount();
System.out.println(teamName+""+docCount);
}
}
}
}
@Test//按每个球队总年薪进行排序,SQL语句实现:select team, sum(salary) as total_salary from player group by team order by total_salary desc;
public void orderBySum(){
SearchRequestBuilder builder = transportClient.prepareSearch("player").setTypes("player");
TermsAggregationBuilder teamGroup = AggregationBuilders.terms("team_group").field("team").order(BucketOrder.count(true));
SumAggregationBuilder sumSalary = AggregationBuilders.sum("sum_salary").field("salary");
TermsAggregationBuilder termsAggregationBuilder = teamGroup.subAggregation(sumSalary);
SearchResponse searchResponse = builder.addAggregation(termsAggregationBuilder).get();
Map<String, Aggregation> stringAggregationMap = searchResponse.getAggregations().asMap();
//System.out.println(stringAggregationMap.toString());
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
Object teamName = bucket.getKey();
long teamNum = bucket.getDocCount();
String sum_salaryTmp = bucket.getAggregations().get("sum_salary").toString();
String tmpStr = sum_salaryTmp.substring(23);
String sum_salary = tmpStr.substring(0, tmpStr.length() - 2);
System.out.println(teamName +" 队共有:"+ teamNum + " 人,总年薪为:"+ sum_salary + "元。");
}
}
}
}