四、使用java客户端简单操作es
4.1 使用java客户端完成创建索引库及文档的添加
- 大致步骤:
- 创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称
- 创建一个客户端Client对象
- 使用client对象创建一个索引库
- 关闭client对象
- 创建一个java工程
- 编写jar包,添加maven的坐标
- 编写测试方法实现创建索引库:
- 步骤如下:
- pom.xml中引入es的依赖:
- 创建测试类并创建索引库:
public class ElasticSearchClientTest{ @Test public void createIndex() throws Exception{ //1. 创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称。 Settings settings= Settings.builder() .put("cluster.name","my-elasticsearch") .build(); // 2. 创建一个客户端Client对象 TransportClient client= new PrebuiltTransportClient(settings); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9303)); // 3. 使用client对象创建一个索引库 client.admin().indices().prepareCreate("index_hello")' // 执行操作 .get(); // 4. 关闭client对象 client.close(); } } 复制代码
4.2 使用Java客户端设置Mappings
- 大致步骤:
- 创建一个Settings对象
- 创建一个Client对象
- 创建一个mapping信息,应该是一个json数据,可以是字符串,也可以是XContextBuilder对象
- 使用client向es服务器发送mapping信息
- 关闭client对象
- 具体测试代码:(在上面的Test类中新建一个Test方法):
@Test public void setMappings() throws Exception{ //1. 创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称。 Settings settings= Settings.builder() .put("cluster.name","my-elasticsearch") .build(); // 2. 创建一个客户端Client对象 TransportClient client= new PrebuiltTransportClient(settings); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9303)); // 3. 创建一个Mappings信息 XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("article") .startObject("properties") .startObject("id") .field("type","long") .field("store",true) .endObject() .startObject("title") .field("type","text") .field("store",true) .field("analyzer","ik_smart") .endObject() .startObject("content") .field("type","text") .field("store",true) .field("analyzer","ik_smart") .endObject() .endObject() .endObject() .endObject() // 使用client把mapping信息设置到索引库中 client.admin().indices() // 设置要做映射的索引 .preparePutMapping("index_hello") // 设置要做映射的type .setType("article") // mapping信息,可以是XContentBuilder对象可以是json格式的字符串 .setSource(builder) // 执行操作 .get(); // 关闭连接 client.close(); } 复制代码
4.3 使用java客户端完成文档新增
- 大致步骤:
- 创建一个Settings对象
- 创建一个Client对象
- 创建一个文档对象,创建一个json格式的字符串,或者使用XContentBuilder
- 使用Client对象把文档添加到索引库中
- 关闭Client
- 操作步骤:
- 我们每次都要创建Settings、Client对象,所以我们将这个操作进行提出来:
public class ElasticSearchClientTest{ private TransportClient client; @Before public void init() throws Exception{ // 创建一个Settings对象 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 创建一个TransPortClient对象 TransportClient client= new PreBuiltTransportClient(settings); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9303)); } } 复制代码
这样子在每次类被实例化之前就会自动init初始化client内的内容了。
- 创建文档:
@Test public void testAddDocument() throws Exception{ // 创建一个文档对象 XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .field("id",1l) .field("title","这是数据的标题") .field("content","这是数据的内容") .endObject(); // 把文档对象添加到索引库 client.prepareIndex() // 设置索引名称 .setIndex("index_hello") // 设置type .setType("article") // 设置文档的id,如果不设置的话会自动生成一个 .setId("id") // 设置文档信息 .setSource(builder) // 执行操作 .get(); // 关闭客户端 client.close(); } 复制代码
- 创建文档的第二种方式(使用对象的方式进行创建):
- pom.xml中引入jackson的相关依赖:
- 创建一个pojo类:
- 添加文档(先使用工具类把pojo转换成json字符串,然后把文档写入索引库)
五. 使用java客户端实现对es的搜索功能
5.1 根据id查询
- 大致步骤:
- 创建一个Client对象
- 创建一个查询对象,可以使用QueryBuilders工具类创建QueryBilder对象。
- 使用client执行查询
- 得到查询的结果
- 取查询结果的总记录数
- 取查询结果列表
- 关闭client
- 代码演示:
public class SearchIndexTest{ private TransportClient client; @Before public void init() throws Exception{ // 创建一个Settings对象 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 创建一个TransPortClient对象 TransportClient client= new PreBuiltTransportClient(settings); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302)); client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9303)); } @Test public void testSearchById() throws Exception{ // 创建一个查询对象 QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1","2"); // 执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello") .setTypes("article") .setQuery(queryBuilder) .get(); // 取查询结果 SearchHits searchHits = searchResponse.getHits(); // 取查询结果的总记录数 System.out.println("查询结果总记录数:"+ searchHits.getTotalHits()); // 查询结果列表 Iterator<SearchHit> iterator = searchHits.iterator(); while(iterator.hasNext()){ SearchHit searchHit = iterator.next(); // 打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); // 取文档的属性 Map<String,Object> document = searchHit.getSource(); System.out.println(document.get("id0")); System.out.println(document.get("title")); System.out.println(document.get("content")); } } } 复制代码
5.2 根据Item查询
@Test public void testQueryByTerm() throws Exception{ // 创建一个QueryBuilder对象 // 参数1:要搜索的字段 // 参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.termQuery("title","北方") // 执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello") .setTypes("article") .setQuery(queryBuilder) .get(); // 取查询结果 SearchHits searchHits = searchResponse.getHits(); // 取查询结果的总记录数 System.out.println("查询结果总记录数:"+ searchHits.getTotalHits()); // 查询结果列表 Iterator<SearchHit> iterator = searchHits.iterator(); while(iterator.hasNext()){ SearchHit searchHit = iterator.next(); // 打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); // 取文档的属性 Map<String,Object> document = searchHit.getSource(); System.out.println(document.get("id0")); System.out.println(document.get("title")); System.out.println(document.get("content")); } } 复制代码
5.3 根据queryString查询
@Test public void testQueryStringQuery() throws Exception { // 创建一个QueryBuilder对象 QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("速度与激情").defaultField("title"); // 执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello") .setTypes("article") .setQuery(queryBuilder) .get(); // 取查询结果 SearchHits searchHits = searchResponse.getHits(); // 取查询结果的总记录数 System.out.println("查询结果总记录数:"+ searchHits.getTotalHits()); // 查询结果列表 Iterator<SearchHit> iterator = searchHits.iterator(); while(iterator.hasNext()){ SearchHit searchHit = iterator.next(); // 打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); // 取文档的属性 Map<String,Object> document = searchHit.getSource(); System.out.println(document.get("id0")); System.out.println(document.get("title")); System.out.println(document.get("content")); } } 复制代码
5.4 分页查询
- 大致步骤:
- 分页需要设置两个值,from和size
- from: 起始行号,从0开始;
- size:每页显示的记录数
- 在client对象执行查询之前,设置分页信息。
- 然后再执行查询:
// 执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello") .setTypes("article") .setQuery(queryBuilder) // 设置分页信息 .setFrom(0) // 每页显示的行数 .setSize(5) .get(); 复制代码
- 注意:
- 代码演示:
5.5 查询结果高亮显示
- 大致步骤:
- 设置高亮显示的字段
- 设置高亮显示的前缀
- 设置高亮显示的后缀
- 高亮的配置:
- 在client对象执行查询之前,设置高亮显示的信息。
- 遍历结果列表时可以从结果中取高亮结果。
- 代码演示:
- 新增高亮对象:
- 查询client内设置高亮信息:
- 拿到查询结果时打印高亮信息:
- 获取更详细的高亮信息(改造步骤3):
六、使用Spring Data ElasticSearch操作ES
5.1 完成Spring Data ElasticSearch的环境搭建
- 什么是Spring Data?
- Spring Data 是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。Spring Data可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括分页、排序等一些常用的功能。
- Spring Data 的官网
- Spring Data 常用的功能模块如下:
- 什么是Spring Data ElasticSearch?
- Spring Data ElasticSearch基于Spring Data API简化ElasticSearch操作,将原始操作ElasticSearch的客户端API进行封装。Spring Data为ElasticSearch项目提供集成搜索引擎。Spring Data ElasticSearch POJO的关键功能区域为中心的模型与ElasticSearch交互,可以轻松地编写一个存储数据访问层;
- 官方网站
- 搭建步骤:
- pom.xml引入Spring Data ElasticSearch:
- 方案一:在resource目录下创建配置文件,配置elasticSearch:
- 方案二:在application.yml中配置:
spring: application: name: es-application data: elasticsearch: cluster-nodes: 192.168.227.136:9300 cluster-name: elasticsearch 复制代码
推荐此方案
- 创建实体类:
- 创建一个Repository:
它继承了ElasticSearchRepository,里面会提供一些常用的方法
5.4 完成Spring Data ElasticSearch的基本增删改查操作
- 创建索引:
- 添加文档:
- 删除文档:
- 更新文档:
它会把原来的这个id匹配的文档给删除掉,然后再新增,就实现了类似更新的功能。
- 查询指定id的文档和查询所有:
5.5 自定义查询方法
- 常用查询命名规则:
- 根据规则定义findByTitle:
- 定义方法:
- 查询代码:
- 根据规则定义or查询方式:
- 定义方法:
- 查询代码:
- 根据规则定义or查询方式且带分页查询:
- 定义方法:
- 查询代码:
自定义查询方法,我们需要根据SpringDataES 的命名规则来命名,这样我们定义了接口就会自动实现功能。如果我们没有实现分页的话,无论es中匹配的有多少条数据,最多也只会默认给我们返回10条。如果需要指定分页,可以使用上面的带分页查询方式。
5.6 使用NativeSearchQuery查询
- 直接使用
章节5.5
中的查询方式,查询的内容比如:"我是程序员",那么它不会再将结果进行分词,所以匹配的结果是我是程序员这个原子词汇。如果要对查询条件再分词,比如我是程序员分词,能够匹配到:我、是、程序、程序员、员的所有数据,我们需要使用queryString方式进行查询。 - 大致步骤:
- 创建一个NativeSearchQuery对象,设置查询条件,QueryBuiilder对象
- 使用ElasticSearchTemplate 对象执行查询
- 取查询结果
- 代码演示:
@Test public void testNativeSearchQuery() throws Exception{ // 创建一个查询对象 NativeSearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.queryStringQUery("Maven是一个构建工具").defaultField("title")) .withPageable(PageRequest.of(0,15)) .build(); // 执行查询 List<Article> articleList = template.queryForList(query,Article.class); articleList.forEach(a-> System.out.println(a)) } 复制代码
稍微麻烦点,但是功能更强,灵活性更高