此文是ElasticSearch入门的第三篇,主要介绍下ES的Java API开发。
1. 环境准备
JDK :1.8
ES :7.15.2(es的客户端版本要和本地部署的服务端版本保持一致)
IDEA:2020.1
新建一个maven项目,导入如下的pom文件
<dependencies>
<dependency>
<!--es的客户端版本与服务端版本保持一致-->
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.15.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.15.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.15.2</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>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</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.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
2. 代码
2.1 创建客户端连接
创建es的客户端有两种方式,一种是通过TransportClient方式,使用内部通信端口;另一种是通过RestHighLevelClient方式,使用http端口,是目前ES官方主推的模式。
因为笔者是学习状态,本文主要还是通过TransportClient方式,两种方式可以转换
private TransportClient transportClient;
private RestHighLevelClient restHighLevelClient;
/**
* 创建客户端连接
* @throws UnknownHostException
*/
@BeforeEach
public void createClinet() throws UnknownHostException {
/**
* 方法一:PreBuiltTransportClient 不被推荐
*/
Settings settings = Settings.builder()
.put("cluster.name", "zero")
.put("client.transport.sniff", "false")//本地测试要设置成false
.build();
transportClient = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300))//内部通信端口
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9301))//内部通信端口
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9302));//内部通信端口
System.out.println("TransportClient 连接成功");
/**
* 方法二:RestHighLevelClient 主推,以rest模式创建客户端
*/
restHighLevelClient = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),//http的通信端口
new HttpHost("localhost", 8200, "http"),//http的通信端口
new HttpHost("localhost",8000,"http")));//http的通信端口
System.out.println("RestHighLevelClient 连接成功");
}
2.2 关闭客户端连接
/**
* 自动关闭客户端连接
*/
@AfterEach
public void closeClinet(){
try {
transportClient.close();
System.out.println("TransportClient 连接关闭成功");
restHighLevelClient.close();
System.out.println("RestHighLevelClient 连接关闭成功");
} catch (IOException e) {
e.printStackTrace();
}
}
2.3 实际操作
/**
* 新建索引
*/
@Test
public void createIndex_1() {
//
transportClient.admin().indices().prepareCreate("mytest_index_1").get();
System.out.println("创建Index成功");
IndexRequest indexRequest = new IndexRequest("mytest_index_1");
indexRequest.type("_doc");
indexRequest.id("1");
indexRequest.source("{" + "\"name\": \"商品2\","
+ "\"price\": \"10\"," + "\"number\": \"10\"" + "}", XContentType.JSON);
try {
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* mapping方式新建索引,并导入数据
* @throws Exception
*/
@Test
public void createIndex_2() throws Exception {
HashMap<String, String> jsonMap = new HashMap<String, String>();
jsonMap.put("name", "zero");
jsonMap.put("sex", "1");
jsonMap.put("age", "25");
jsonMap.put("address", "hf");
IndexResponse indexResponse = transportClient.prepareIndex("mytest_index_2", "doc", "2")
.setSource(jsonMap)
.get();
System.out.println("创建Index成功");
}
/**
* 删除索引
*/
@Test
public void deleteIndex(){
transportClient.admin().indices().prepareDelete("mytest_index_2").get();
System.out.println("删除索引成功");
}
/**
* 查询一条数据
*/
@Test
public void getSearch(){
GetResponse documentField = transportClient.prepareGet("employee","_doc","1").get();
//直接输出string类型的结果字符串
System.out.println(documentField.getSourceAsString());
//输出index、type、id等内部属性字段值
String index = documentField.getIndex();
String type_ = documentField.getType();
String id = documentField.getId();
System.out.println("index: "+index+", type: "+type_+", id: "+id);
//输出自定的字段的结果
Map<String, Object> source = documentField.getSource();
for(String field:source.keySet()){
System.out.println(field +" : "+source.get(field));
}
//输出某个自定义字段的值
String name = (String) documentField.getSource().get("name");
System.out.println(name);
}
/**
* 查询所有的数据
*/
@Test
public void searchAllData(){
SearchResponse searchResponse = transportClient.prepareSearch("employee")
// .setTypes("_doc")
.setQuery(new MatchAllQueryBuilder())
.get();
SearchHits searchHits = searchResponse.getHits();
SearchHit[] hits = searchHits.getHits();
for(SearchHit hit:hits){
String sourceString = hit.getSourceAsString();
System.out.println(sourceString);
};
}
/**
* 范围查询
*/
@Test
public void rangeQuery(){
SearchResponse searchResponse = transportClient.prepareSearch("employee")
.setQuery(new RangeQueryBuilder("sal").gte(10000).lte(20000))
.get();
SearchHits hits = searchResponse.getHits();
SearchHit[] hits1 = hits.getHits();
for (SearchHit documentFields : hits1) {
System.out.println(documentFields.getSourceAsString());
}
}
/**
* 词条查询:term查询
* setFetchSource(a,b),a和b必须同时为String或者String[]
*/
@Test
public void termQuery(){
String[] include_source = {"name","age","job"};
String[] exclude_a = null;
String[] exclude_b = {"age"};
SearchResponse searchResponse = transportClient.prepareSearch("employee")
.setQuery(new TermQueryBuilder("job", "java"))
// .setFetchSource(include_source,exclude_a)//设置只返回指定的字段或者不回哪些字段,
.setFetchSource(include_source,exclude_b) //设置不返回age
.get();
SearchHits hits = searchResponse.getHits();
SearchHit[] hits1 = hits.getHits();
for (SearchHit documentFields : hits1) {
System.out.println(documentFields.getSourceAsString());
}
}
/**
* fuzzy_search 模糊查询
* .fuzziness(Fuzziness.distancce))
* 0 : 1或2个字符的字符串
* 1 : 4或5个字符的字符串
* 2 : 多于5个字符的字符串字符
*/
@Test
public void fuzzy_search(){
SearchResponse searchResponse = transportClient.prepareSearch("employee")
.setQuery(new FuzzyQueryBuilder("job","jaVA").fuzziness(Fuzziness.TWO))
.get();
SearchHits searchHit = searchResponse.getHits();
SearchHit[] hits = searchHit.getHits();
for (SearchHit hit:hits) {
System.out.println(hit.getSourceAsString());
}
}
/**
* boolQuery 多条件组合查询
*/
@Test
public void boolQuery(){
int pageSize = 3;
int pageNum = 2;
int startNum = (pageNum-1)*pageSize;
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("job","html");
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("sal").gt("10000").lt("25000");
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("gender","fe").fuzziness(Fuzziness.ONE);
SearchResponse searchResponse = transportClient.prepareSearch("employee")
.setQuery(QueryBuilders.boolQuery().must(termQueryBuilder)
.should(QueryBuilders.boolQuery().must(rangeQueryBuilder).must(fuzzyQueryBuilder)))
.addSort("id",SortOrder.ASC)
.setFrom(startNum)
.setSize(pageSize)
.get();
SearchHits searchHit = searchResponse.getHits();
SearchHit[] hits = searchHit.getHits();
for (SearchHit hit:hits) {
System.out.println(hit.getSourceAsString());
}
}
/**
* 分页查询
*/
@Test
public void pageQuery(){
int pageSize = 5;
int pageNum = 1;
int startNum = (pageNum-1)*pageSize;
SearchResponse searchResponse = transportClient.prepareSearch("employee")
.setQuery(QueryBuilders.matchAllQuery())
.addSort("id", SortOrder.ASC)
.setSize(pageSize)
.setFrom(startNum)
.get();
SearchHits searchHits = searchResponse.getHits();
SearchHit[] hits = searchHits.getHits();
for(SearchHit searchHit:hits){
System.out.println(searchHit.getSourceAsString());
}
}