springboot整合ES
ES提供的Java客户端——RestClient
RestClient是官方推荐使用的,它包括两种:Java Low Level REST Client和 Java High Level REST Client。ES在6.0之后提供 Java High Level REST Client, 两种客户端官方更推荐使用 Java High Level REST Client,不过当前它还处于完善中,有些功能还没有(如果它有不支持的功能,则使用Java Low Level REST Client。)。
增加es依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.1</version>
</dependency>
这两个依赖会存在问题
java.lang.NoSuchMethodError: org.elasticsearch.client.Request.<init>(Ljava/lang/String;Ljava/lang/String
可以通过更改版本来解决,原因是两个jar包中都有Request这个类,包名和项目名还是一样的,根据双亲委派加载类机制,这时high-level-client中的就不会加载,(同包名和项目名的类在不通jar中只加载一个)
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
配置文件
server:
port: ${port:40100}
spring:
application:
name: xc-service-search
xuecheng: #自定义属性项
elasticsearch:
host-list: ${eshostlist:127.0.0.1:9200} #多个节点中间用逗号分隔
ES配置类
**
* ElasticsearchConfig class
*
* @author : xwx
* @date : 2019/6/20
*/
@Configuration
public class ElasticsearchConfig {
@Value("${xuwenxiang.elasticsearch.host-list}")
private String hostList;
@Bean
public RestHighLevelClient restHighLevelClient() {
return new RestHighLevelClient(RestClient.builder(getHttpHostList(hostList)));
}
private HttpHost[] getHttpHostList(String hostList) {
String[] hosts = hostList.split(",");
HttpHost[] httpHostArr = new HttpHost[hosts.length];
for (int i = 0; i < hosts.length; i++) {
String[] items = hosts[i].split(":");
httpHostArr[i] = new HttpHost(items[0], Integer.parseInt(items[1]), "http");
}
return httpHostArr;
}
// rest low level client
@Bean
public RestClient restClient() {
return RestClient.builder(getHttpHostList(hostList)).build();
}
}
Java客户端主要用途有:
(1)在现有集群上执行标准索引,获取,删除和搜索操作
(2)在正在运行的集群上执行管理任务
- 修改时如果该文档不存在会报错
- 删除时如果该文档不存在不会报错
/**
* TestES class
*
* @author : xwx
* @date : 2019/6/20
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestESRestClient {
@Autowired
RestHighLevelClient restHighLevelClient; //ES连接对象
@Autowired
RestClient restClient;
/**
* 新建索引库
*
* @throws IOException
*/
@Test
public void CreateIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("index_xuwenxiang_test");
request.settings(Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0));
//通过ES连接对象获取索引库管理对象
IndicesClient indicesClient = restHighLevelClient.indices();
CreateIndexResponse response=indicesClient.create(request);
System.out.print(response);
}
}
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties")
.startObject("test").field("type","text").endObject()
.startObject("title").field("type","text").endObject()
.endObject().endObject();
PutMappingRequest request= Requests.putMappingRequest("index_xuwenxiang_test").type("doc").source(mapping);
client.admin().indices().putMapping(request).actionGet();
/**
* 新增文档
*
* @throws IOException
*/
@Test
public void insertDoc() throws IOException {
Map<String ,Object> jsonMap=new HashMap<>();
jsonMap.put("test","测试测试测试4");
jsonMap.put("title","标题标题标题4");
IndexRequest request=new IndexRequest("index_xuwenxiang_old_create","doc","4").source(jsonMap);
client.prepareIndex("index_xuwenxiang_old_create","doc","4").setSource(jsonMap).execute().actionGet();
}
/**
* 查询
* @throws IOException
*/
@Test
public void getDoc()throws IOException{
GetResponse getResponse =client.prepareGet("index_xuwenxiang_old_create","doc","4").get();
System.out.print(getResponse);
}
/**
* 修改
*
* @throws IOException
*/
@Test
public void update() throws IOException {
UpdateRequest updateRequest=new UpdateRequest("index_xuwenxiang_old_create","doc","4");
Map<String, Object> docMap = new HashMap<>();
docMap.put("test", "update测试测试测试4_old");
docMap.put("title", "update测试测试测试4_old");
updateRequest.doc(docMap);
UpdateResponse response = client.update(updateRequest).actionGet();
System.out.println(response);
}
/**
* 删除
*
* @throws IOException
*/
@Test
public void delete() throws IOException {
DeleteRequest request = new DeleteRequest("index_xuwenxiang_old_create", "doc", "4");
DeleteResponse response = client.delete(request).actionGet();
System.out.println(response);
}
/**
* 新建索引库
*
* @throws IOException
*/
@Test
public void createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("index_xuwenxiang_test_new");
request.settings(Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0));
//通过ES连接对象获取索引库管理对象
IndicesClient indicesClient = restHighLevelClient.indices();
CreateIndexResponse response = indicesClient.create(request);
System.out.print(response);
}
/**
* 新建索引mapping
*
* @throws IOException
*/
@Test
public void createMapping() throws IOException {
IndexRequest indexRequest=new IndexRequest();
XContentBuilder builder= JsonXContent.contentBuilder()
.startObject()
.startObject("properties")
.startObject("title")
.field("type","text")
.field("analyzer","ik_max_word")
.endObject()
.startObject("content")
.field("type","text")
.field("analyzer","ik_max_word")
.endObject()
.endObject()
.endObject();
indexRequest.source(builder);
// 生成json字符串
String source = indexRequest.source().utf8ToString();
HttpEntity entity = new NStringEntity(source, ContentType.APPLICATION_JSON);
// 使用RestClient进行操作 而非rhlClient
Response response = restClient.performRequest("post", "/index_xuwenxiang_test_new_one/doc/_mapping", Collections.<String, String> emptyMap(),
entity);
System.out.println(response);
}
/**
* 新增文档方式一
*
* @throws IOException
*/
@Test
public void insertDocOne() throws IOException {
Map<String ,Object> jsonMap=new HashMap<>();
jsonMap.put("test","测试测试测试");
jsonMap.put("title","标题标题标题");
IndexRequest request=new IndexRequest().source(jsonMap);
// 生成json字符串
String source = request.source().utf8ToString();
HttpEntity entity = new NStringEntity(source, ContentType.APPLICATION_JSON);
restClient.performRequest("post","/index_xuwenxiang_old_create/doc/1", Collections.emptyMap(),entity);
}
/**
* 新增文档方式二
*
* @throws IOException
*/
@Test
public void insertDocMethodTwo() throws IOException {
Map<String ,Object> jsonMap=new HashMap<>();
jsonMap.put("test","测试测试测试2");
jsonMap.put("title","标题标题标题2");
IndexRequest request=new IndexRequest("index_xuwenxiang_old_create","doc","2").source(jsonMap);
restHighLevelClient.index(request);
}
/**
* 修改
*
* @throws IOException
*/
@Test
public void update() throws IOException {
UpdateRequest updateRequest=new UpdateRequest("index_xuwenxiang_old_create","doc","4");
Map<String, Object> docMap = new HashMap<>();
docMap.put("test", "update测试测试测试4");
docMap.put("title", "update测试测试测试4");
updateRequest.doc(docMap);
UpdateResponse response = restHighLevelClient.update(updateRequest);
System.out.println(response);
}
/**
* 删除
*
* @throws IOException
*/
@Test
public void delete() throws IOException {
DeleteRequest request = new DeleteRequest("index_xuwenxiang_old_create", "doc", "4");
DeleteResponse response = restHighLevelClient.delete(request);
System.out.println(response);
}
踩过的坑
- 用XContentFactory.jsonBuilder的时候如果field用一个参数就会报错
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties")
.startObject("test").field("text").endObject()
.startObject("title").field("text").endObject()
.endObject().endObject();
- 索引必须存在
- Requests.putMappingRequest("index_xuwenxiang_testfff")
- 如果不存在就会报错:no such index