搜索引擎ElasticSearch18_ElasticSearch编程操作5
一、使用Java客户端管理ES
1、操作es
步骤:
1. 创建索引库
1)创建一个Java工程
2)添加jar包,添加maven的坐标
3)编写测试方法实现创建索引库
1、创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称
2、创建一个客户端Client对象
3、使用Client对象创建一个索引库
4、关闭Client对象
2. 使用Java客户端设置Mappings
1)创建一个Settings对象
2)创建一个Client对象
3)创建一个mapping信息,应是一个json数据,可以是字符串,也可以是XContentBuilder对象
4)使用Client向es服务器发送mapping信息
5)关闭Client对象
3. 添加文档-数据
1)创建一个Settings对象
2)创建一个Client对象
3)创建一个文档对象,创建一个json格式的字符串,或者使用XContentBuilder对象
4)使用Client对象把文档添加到索引库中
5)关闭Client对象
4. 添加文档第二种方式
1)创建一个pojo类
2)使用工具类把pojo转换成json字符串
3)把文档写入索引库
4)关闭Client客户端
2、使用es客户端实现搜索
1. 根据id搜索
2. 根据Term查询(关键词)
3. QueryString查询方式(带分析的查询)
查询步骤:
1)创建一个Client对象
2)创建一个查询对象,QueryBuilders工具类来创建QueryBuilder对象
3)使用client执行查询
4)得到查询的结果
5)取查询结果的总记录数
6)取查询结果列表
7)关闭client
4. 分页处理
在client对象执行查询之前,设置分页信息,然后再执行查询。
分页需要设置两个值:from、size
from:起始的行号,从0开始
size:每页显示的记录数
5. 查询结果高亮显示
1、高亮的配置
1)设置高亮显示的字段
2)设置高亮显示的前缀
3)设置高亮显示的后缀
2、在client对象执行查询之前,设置高亮显示的信息。
3、遍历结果列表时可以从结果中取高亮结果
二、创建工程,导入坐标
先创建一个空项目:ElasticSearchClient,然后创建一个module-maven工程:es-first
pom.xml坐标
<dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>5.6.8</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.6.8</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.24</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
二、创建索引index
package com.itheima.es; 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 java.net.InetAddress; 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对象创建一个索引库 //.get() 执行操作 client.admin().indices().prepareCreate("index_hello").get(); // 4、关闭client对象 client.close(); } }
三、创建映射mapping
package com.itheima.es; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.client.Requests; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Test; import java.net.InetAddress; public class ElasticSearchClientTest { @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)); /*{ "article": { "properties": { "id": { "store": true, "type": "long" }, "title": { "analyzer": "standard", "store": true, "type": "text" }, "content": { "analyzer": "standard", "store": true, "type": "text" } } }*/ XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("article") .startObject("properties") .startObject("id") .field("type","long") .field("store",true) .endObject() .startObject("title") .field("analyzer","standard") .field("type","text") .field("store",true) .endObject() .startObject("content") .field("analyzer","standard") .field("type","text") .field("store",true) .endObject() .endObject() .endObject() .endObject(); //使用client把mapping信息设置到索引库中-推荐 client.admin().indices() //设置要做映射的索引 .preparePutMapping("index_hello") //设置要做映射的type .setType("article") //mapping信息,可以是XContextBuilder对象也可以是json格式的字符串 .setSource(builder) //执行操作 .get(); //也可以使用下面这种方法添加mapping信息-不推荐 // PutMappingRequest mapping = Requests.putMappingRequest("index_hello").type("article").source(builder); // client.admin().indices().putMapping(mapping).get(); client.close(); } }
四、建立文档document
1、建立文档(通过XContentBuilder)
package com.itheima.es; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.client.Requests; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Before; import org.junit.Test; import java.net.InetAddress; public class ElasticSearchClientTest { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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 testAddDocument() throws Exception { //创建一个client对象 //创建一个文档对象 XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .field("id",1l) .field("title","ElasticSearch是一个基于Lucene的搜索服务器") .field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。") .endObject(); //把文档对象添加到索引库 // client.prepareIndex("index_hello","article","1").setSource(builder).get(); client.prepareIndex() //设置索引名称 .setIndex("index_hello") //设置type .setType("article") //设置文档id,如果不设置的话自动生成一个id .setId("1") //设置文档信息 .setSource(builder) //执行操作 .get(); client.close(); } }
2、建立文档(使用Jackson转换实体)
1)创建Article实体
public class Article { private Integer id; private String title; private String content; getter/setter... }
2)添加jackson坐标
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.8.1</version> </dependency>
3)代码实现
package com.itheima.es; import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.client.Requests; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; 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.junit.Before; import org.junit.Test; import java.io.IOException; import java.net.InetAddress; public class ElasticSearchClientTest { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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 testAddDocument2() throws Exception{ //创建一个Article对象 Article article = new Article(); //设置对象的属性 article.setId(2l); article.setTitle("搜索工作其实很快乐"); article.setContent("我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,"); //把Article对象转换成json格式的字符串 String jsonDocument = new ObjectMapper().writeValueAsString(article); System.out.println(jsonDocument); //使用Client对象把文档写入索引库 client.prepareIndex("index_hello","article","2") .setSource(jsonDocument, XContentType.JSON).get(); //关闭客户端 client.close(); } }
五、查询文档操作
1、根据文档ID查询文档
package com.itheima.es; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Before; import org.junit.Test; import java.net.InetAddress; import java.util.Iterator; import java.util.Map; public class SearchIndex { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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{ //创建一个client对象 //创建一个查询对象 QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1","2"); //执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder).get(); //取查询结果 SearchHits hits = searchResponse.getHits(); //取查询结果的总记录数 System.out.println("查询结果总记录数:"+hits.getTotalHits()); //查询结果列表 // SearchHit[] hits1 = hits.getHits(); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ SearchHit searchHit = iterator.next(); //打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); //取文档的属性 System.out.println("-----------文档的属性"); Map<String, Object> document = searchHit.getSource(); System.out.println(document.get("id")); System.out.println(document.get("title")); System.out.println(document.get("content")); } //关闭client client.close(); } }
2、Term关键词查询
package com.itheima.es; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Before; import org.junit.Test; import java.net.InetAddress; import java.util.Iterator; import java.util.Map; public class SearchIndex { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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)); } private void search(QueryBuilder queryBuilder) throws Exception{ //创建一个client对象 //创建一个查询对象 //执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder).get(); //取查询结果 SearchHits hits = searchResponse.getHits(); //取查询结果的总记录数 System.out.println("查询结果总记录数:"+hits.getTotalHits()); //查询结果列表 // SearchHit[] hits1 = hits.getHits(); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ SearchHit searchHit = iterator.next(); //打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); //取文档的属性 System.out.println("-----------文档的属性"); Map<String, Object> document = searchHit.getSource(); System.out.println(document.get("id")); System.out.println(document.get("title")); System.out.println(document.get("content")); } //关闭client client.close(); } @Test public void testQueryByTerm() throws Exception{ //创建一个QueryBuilder对象 //参数1:要搜索的字段 //参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.termQuery("title","搜"); //执行查询 search((queryBuilder)); } }
3、QueryString字符串查询
@Test public void testQueryString() throws Exception{
//不指定field,则在所有field进行查询 QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("钢索").defaultField("title"); search(queryBuilder); }
六、查询文档分页操作
1、批量插入数据
package com.itheima.es; import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.client.Requests; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; 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.junit.Before; import org.junit.Test; import java.net.InetAddress; public class ElasticSearchClientTest { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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 testAddDocument3() throws Exception{ for (int i = 3; i <= 100; i++) { Article article = new Article(); article.setId(i); article.setTitle(i+"搜索工作其实很快乐"); article.setContent(i+"我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,"); //把Article对象转换成json格式的字符串 String jsonDocument = new ObjectMapper().writeValueAsString(article); System.out.println(jsonDocument); //使用Client对象把文档写入索引库 client.prepareIndex("index_hello","article",i+"") .setSource(jsonDocument, XContentType.JSON).get(); } //关闭客户端 client.close(); } }
2、分页查询
package com.itheima.es; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Before; import org.junit.Test; import java.net.InetAddress; import java.util.Iterator; import java.util.Map; public class SearchIndex { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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)); } private void search(QueryBuilder queryBuilder) throws Exception{ //创建一个client对象 //创建一个查询对象 //执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder) //设置分页信息,from-从第几条开始检索,默认从0开始 .setFrom(10) //每页显示的记录数,默认是10条 .setSize(5) .get(); //取查询结果 SearchHits hits = searchResponse.getHits(); //取查询结果的总记录数 System.out.println("查询结果总记录数:"+hits.getTotalHits()); //查询结果列表 Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ SearchHit searchHit = iterator.next(); //打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); //取文档的属性 System.out.println("-----------文档的属性"); Map<String, Object> document = searchHit.getSource(); System.out.println(document.get("id")); System.out.println(document.get("title")); System.out.println(document.get("content")); } //关闭client client.close(); } @Test public void testQueryString() throws Exception{ QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("搜索").defaultField("title"); search(queryBuilder); } }
七、查询结果高亮操作
1、什么是高亮显示
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮
百度搜索关键字"传智播客"
京东商城搜索"笔记本"
2、高亮显示的html分析
通过开发者工具查看高亮数据的html代码实现:
ElasticSearch可以对查询出的内容中关键字部分进行标签和样式的设置,但是你需要告诉ElasticSearch使用什么标签对高亮关键字进行包裹
3、高亮显示代码实现
package com.itheima.es; 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.InetSocketTransportAddress; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.junit.Before; import org.junit.Test; import java.net.InetAddress; import java.util.Iterator; import java.util.Map; public class SearchIndex { private TransportClient client; @Before public void init() throws Exception{ // 1、创建一个settings对象,相当于是一个配置信息。主要配置集群的名称 Settings settings = Settings.builder().put("cluster.name","my-elasticsearch").build(); // 2、创建一个客户端Client对象 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)); } private void search(QueryBuilder queryBuilder,String highlightField) throws Exception{ HighlightBuilder highlightBuilder = new HighlightBuilder(); //高亮显示的字段 highlightBuilder.field(highlightField); highlightBuilder.preTags("<em>"); highlightBuilder.postTags("</em>"); //创建一个client对象 //创建一个查询对象 //执行查询 SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder) //设置分页信息,from-从第几条开始检索,默认从0开始 .setFrom(10) //每页显示的记录数,默认是10条 .setSize(5) //设置高亮信息 .highlighter(highlightBuilder) .get(); //取查询结果 SearchHits hits = searchResponse.getHits(); //取查询结果的总记录数 System.out.println("查询结果总记录数:"+hits.getTotalHits()); //查询结果列表 // SearchHit[] hits1 = hits.getHits(); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ SearchHit searchHit = iterator.next(); //打印文档对象,以json格式输出 System.out.println(searchHit.getSourceAsString()); //取文档的属性 System.out.println("-----------文档的属性"); Map<String, Object> document = searchHit.getSource(); System.out.println(document.get("id")); System.out.println(document.get("title")); System.out.println(document.get("content")); System.out.println("**************************高亮结果"); Map<String, HighlightField> highlightFields = searchHit.getHighlightFields(); System.out.println(highlightFields); //取title高亮显示的结果 Text[] fragments = highlightFields.get(highlightField).getFragments(); for (Text fragment: fragments) { System.out.println(fragment); } } //关闭client client.close(); } @Test public void testQueryStringHightLight() throws Exception{ QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("搜索").defaultField("title"); search(queryBuilder,"title"); } }