Elasticsearch Java API 索引管理和数据增删改查操作
ElasticSearch 的环境安装请参考 ElasticSearch 6.0.0 安装配置 。
这节主要通过 Java API 操作 Elasticsearch。
Maven 依赖
添加 maven pom 依赖,pom.xml 代码如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sun.elasticsearch</groupId>
<artifactId>Elasticsearch01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- Elasticsearch核心依赖包 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.5.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 日志依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>
JAVA API 连接 ElasticSearch
注意,我们通过浏览器 http://192.168.1.140:9200
访问可以正常访问 ElaticSearch,默认配置中,9200
端口是用于 Http 协议访问的,如果通过 Java API 客户端访问需要通过 9300
端口。
package com.sun.elasticsearch;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Elasticsearch 的基本测试
*/
public class ElasticsearchTest1 {
private Logger logger = LoggerFactory.getLogger(ElasticsearchTest1.class);
public final static String HOST = "192.168.1.140";
// http 请求的端口是 9200,客户端是 9300
public final static int PORT = 9300;
/**
* 测试 Elasticsearch 客户端连接
* @return void
* @throws UnknownHostException
*/
@SuppressWarnings("resource")
@Test
public void test1() throws UnknownHostException {
// 创建客户端
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(HOST), PORT));
logger.debug("Elasticsearch connect info:" + client.toString());
// 关闭客户端
client.close();
}
}
Elasticsearch 索引库的创建
为了简化代码,我们在修改 Junit 测试类,在方法执行之前连接 Elasticsearch,方法调用之后自动执行关闭 Elasticsearch,通过 @Before
和 @After
注解实现,具体代码如下:
private Logger logger = LoggerFactory.getLogger(ElasticsearchTest2.class);
public final static String HOST = "192.168.1.140";
// http 请求的端口是 9200,客户端是 9300
public final static int PORT = 9300;
private TransportClient client = null;
/**
* 获取客户端连接信息
* @return void
* @throws UnknownHostException
*/
@SuppressWarnings({ "resource", "unchecked" })
@Before
public void getConnect() throws UnknownHostException {
client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(HOST),PORT));
logger.info("连接信息:" + client.toString());
}
/**
* 关闭连接
* @return void
*/
@After
public void closeConnect() {
if(null != client) {
logger.info("执行关闭连接操作...");
client.close();
}
}
}
创建索引库:
/**
* 创建索引库
*
* 需求:创建一个索引库为:msg 消息队列,类型为:tweet,id 为 1,
* 索引库的名称必须为小写
*
* @return void
* @throws IOException
*/
@Test
public void addIndex1() throws IOException {
IndexResponse response = client.prepareIndex("msg", "tweet", "1")
.setSource(XContentFactory.jsonBuilder()
.startObject().field("userName", "张三")
.field("sendDate", new Date())
.field("msg", "你好李四")
.endObject())
.get();
logger.info("索引名称:" + response.getIndex() + "\n类型:" + response.getType()
+ "\n文档ID:" + response.getId() + "\n当前实例状态:" + response.status());
}
索引库名称必须为小写,如果为大写会报 [MQ] InvalidIndexNameException[invalid index name [MQ], must be lowercase]
错误。
此时运行代码控制台打印出如下结果,说明此时已经在 ElasticSearch 中创建成功一个为 msg 的索引库。
向索引库中添加 json 字符串
@Test
public void addIndex2() {
String jsonStr = "{" +
"\"userName\":\"张三\"," +
"\"sendDate\":\"2017-11-30\"," +
"\"msg\":\"你好李四\"" +
"}";
IndexResponse response = client.prepareIndex("weixin", "tweet")
.setSource(jsonStr,XContentType.JSON)
.get();
logger.info("json索引名称:" + response.getIndex()
+ "\njson类型:" + response.getType()
+ "\njson文档ID:" + response.getId()
+ "\n当前实例json状态:" + response.status());
}
执行结果:
向索引库添加一个 Map 集合
@Test
public void addIndex3() {
Map<String, Object> map = new HashMap<String,Object>();
map.put("userName", "张三");
map.put("sendDate", new Date());
map.put("msg", "你好李四");
IndexResponse response = client.prepareIndex("momo", "tweet")
.setSource(map)
.get();
logger.info("map索引名称:" + response.getIndex()
+ "\n map类型:" + response.getType()
+ "\n map文档ID:" + response.getId()
+ "\n当前实例map状态:" + response.status());
}
执行结果:
向索引库添加 JsonObject
@Test
public void addIndex4() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("userName", "张三");
jsonObject.addProperty("sendDate", "2017-11-23");
jsonObject.addProperty("msg","你好李四");
IndexResponse response = client.prepareIndex("qq", "tweet")
.setSource(jsonObject, XContentType.JSON)
.get();
logger.info("jsonObject索引名称:" + response.getIndex()
+ "\n jsonObject类型:" + response.getType()
+ "\n jsonObject文档ID:" + response.getId()
+ "\n当前实例jsonObject状态:" + response.status());
}
执行结果:
从索引库查询数据
@Test
public void getData1() {
GetResponse getResponse = client.prepareGet("msg", "tweet", "1").get();
logger.info("索引库的数据:" + getResponse.getSourceAsString());
}
执行结果:
更新索引库数据
@Test
public void updateData() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("userName", "王五");
jsonObject.addProperty("sendDate", "2008-08-08");
jsonObject.addProperty("msg", "你好,张三,好久不见");
UpdateResponse updateResponse = client.prepareUpdate("msg", "tweet", "1")
.setDoc(jsonObject.toString(),XContentType.JSON)
.get();
logger.info("updateResponse索引名称:" + updateResponse.getIndex()
+ "\n updateResponse类型:" + updateResponse.getType()
+ "\n updateResponse文档ID:" + updateResponse.getId()
+ "\n当前实例updateResponse状态:" + updateResponse.status());
}
执行结果:
更新结束之后,再次调用从索引库获取数据执行结果如下:
删除索引库的数据
@Test
public void deleteData() {
DeleteResponse deleteResponse = client.prepareDelete("msg", "tweet", "1").get();
logger.info("deleteResponse索引名称:" + deleteResponse.getIndex()
+ "\n deleteResponse类型:" + deleteResponse.getType()
+ "\n deleteResponse文档ID:" + deleteResponse.getId()
+ "\n当前实例deleteResponse状态:" + deleteResponse.status());
}
执行结果:
删除之后再次执行从索引库获取数据,结果如下:
索引库的数据变为 null
了,说明删除成功。