ElasticSearch操作入门
1 目标
- 创建文档(JSON/Map)
- ES数据搜索
2 讲解
2.1 工程搭建
(1)创建Maven工程
工程坐标如下:
<groupId>com.itheima</groupId> <artifactId>elasticsearch-day1-demo1</artifactId> <version>1.0-SNAPSHOT</version>
(2)pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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.itheima</groupId> <artifactId>elasticsearch-day1-demo1</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--ES包--> <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> </project>
2.2 新建索引+添加文档
使用创建索引(index)+类型(type)+自动创建映射(Elasticsearch帮助我们根据存储的字段自动建立映射,后续讲完分词器后,手动建立映射)
(1)基于jsonBuilder创建索引
创建测试类com.itheima.test.ElasticsearchTest
,并在类中创建testCreateIndexJsonDemo1方法,实现创建索引,代码如下:
/*** * 组织Document数据(使用ES的api构建json) */ @Test public void testCreateIndexJsonDemo1() throws Exception { /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); //构建文档对象 XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); builder.field("id",1); builder.field("title","ElasticSearch是一个基于Lucene的搜索服务器。"); builder.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"); builder.endObject(); //使用TransportClient对象创建文档 client.prepareIndex("blog1","article","1").setSource(builder).get(); //关闭资源 client.close(); }
访问<http://localhost:9100/>
,效果如下:
(2)使用Map创建索引
在测试类com.itheima.test.ElasticsearchTest
,中创建testCreateIndexMapDemo2方法,实现创建索引,代码如下:
/*** * 使用Map创建索引 */ @Test public void testCreateIndexMapDemo2() throws Exception { /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的TCP通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); //构建文档对象 Map<String,Object> map = new HashMap<String,Object>(); map.put("id",2); map.put("title","2-ElasticSearch是一个基于Lucene的搜索服务器"); map.put("content","2-它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。"); //使用TransportClient对象创建文档 client.prepareIndex("blog1","article","2").setSource(map).get(); //关闭资源 client.close(); }
访问<http://localhost:9100/>
,效果如下:
2.3 搜索文档数据
(1)根据ID查询(不走索引)
/*** * 根据ID查询 */ @Test public void testQueyById() throws Exception{ /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); //查询数据 GetResponse response = client.prepareGet("blog1", "article", "1").get(); //获取结果集数据 String result = response.getSourceAsString(); System.out.println(result); }
此时直接根据ID查询,不会走索引域,直接根据ID定位数据,执行后结果如下:
{"id":1,"title":"ElasticSearch是一个基于Lucene的搜索服务器。","content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"}
(2)查询全部(不走索引)
/*** * 查询所有,不走索引 */ @Test public void testQueryAll() throws Exception{ /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); /** * 搜索数据 */ SearchResponse response = client .prepareSearch("blog1") .setTypes("article") .setQuery(QueryBuilders.matchAllQuery()) //设置查询条件,QueryBuilders.matchAllQuery()查询所有 .get(); //处理结果 SearchHits hits = response.getHits(); //总记录数 long totalHits = hits.getTotalHits(); //获取数据结果集 Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ //获取数据 SearchHit hit = iterator.next(); //获取指定域数据 String title = hit.getSource().get("title").toString(); //获取所有数据,并转成JSON字符串 String result = hit.getSourceAsString(); System.out.println(title); System.out.println(result); } }
查询所有数据,不走索引域,直接获取所有结果记录,控制台输出结果如下:
2-ElasticSearch是一个基于Lucene的搜索服务器 {"id":2,"title":"2-ElasticSearch是一个基于Lucene的搜索服务器","content":"2-它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。"} ElasticSearch是一个基于Lucene的搜索服务器。 {"id":1,"title":"ElasticSearch是一个基于Lucene的搜索服务器。","content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"}
(3)字符串查询
/*** * 字符串查询 */ @Test public void testQueryByString() throws Exception{ /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); /** * 搜索数据 */ SearchResponse response = client .prepareSearch("blog1") .setTypes("article") // 默认在所有的域上进行搜索,搜索“搜索”;如果添加.field("title"):表示只在title域进行搜索 .setQuery(QueryBuilders.queryStringQuery("搜索").field("title")) .get(); //处理结果 SearchHits hits = response.getHits(); //总记录数 long totalHits = hits.getTotalHits(); //获取数据结果集 Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ //获取数据 SearchHit hit = iterator.next(); //获取指定域数据 String title = hit.getSource().get("title").toString(); //获取所有数据,并转成JSON字符串 String result = hit.getSourceAsString(); System.out.println(title); System.out.println(result); } }
此时会走索引域,搜索结果如下:
2-ElasticSearch是一个基于Lucene的搜索服务器 {"id":2,"title":"2-ElasticSearch是一个基于Lucene的搜索服务器","content":"2-它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。"} ElasticSearch是一个基于Lucene的搜索服务器。 {"id":1,"title":"ElasticSearch是一个基于Lucene的搜索服务器。","content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"}
(4)词条搜索
/*** * 词条查询 */ @Test public void testQueryByTerm() throws Exception{ /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); /** * 搜索数据 */ SearchResponse response = client .prepareSearch("blog1") .setTypes("article") // 设置查询条件 .setQuery(QueryBuilders.termQuery("title","搜索")) .get(); //处理结果 SearchHits hits = response.getHits(); //总记录数 long totalHits = hits.getTotalHits(); //获取数据结果集 Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ //获取数据 SearchHit hit = iterator.next(); //获取指定域数据 String title = hit.getSource().get("title").toString(); //获取所有数据,并转成JSON字符串 String result = hit.getSourceAsString(); System.out.println(title); System.out.println(result); } //关闭资源 client.close(); }
搜不到结果:为什么?
(5)模糊查询(通配符查询)
*:表示所有的任意的多个字符组成
?:表示1个任意的字符
/*** * 通配符查询 */ @Test public void testQueryByKeyword() throws Exception{ /*** * 创建TransportClient对象 * Settings:表示集群的设置 * EMPTY:表示没有集群的配置 * Settings.EMPTY:不使用集群 */ TransportClient client = new PreBuiltTransportClient(Settings.EMPTY); /**** * 配置链接信息 * 127.0.0.1:Elasticsearch的IP地址 * 9300:Elasticsearch的通信端口 */ client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300)); /** * 搜索数据 */ SearchResponse response = client .prepareSearch("blog1") .setTypes("article") // 设置查询条件 .setQuery(QueryBuilders.wildcardQuery("title","*搜索*")) .get(); //处理结果 SearchHits hits = response.getHits(); //总记录数 long totalHits = hits.getTotalHits(); //获取数据结果集 Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()){ //获取数据 SearchHit hit = iterator.next(); //获取指定域数据 String title = hit.getSource().get("title").toString(); //获取所有数据,并转成JSON字符串 String result = hit.getSourceAsString(); System.out.println(title); System.out.println(result); } //关闭资源 client.close(); }
搜素不到结果。
词条查询和通配符查询不能查询到数据,为什么呢?
2.4 词条总结
词条: 就是将文本内容存入搜索服务器,搜索服务器进行分词之后的最小的词(不能再切分)
例如:“ElasticSearch是一个基于Lucene的搜索服务器”
分词(好的): ElasticSearch、是、一个、基于、Lucene、搜索、服务、服务器
默认单字分词(差的): ElasticSearch、 是、一、个、基、于、搜、索、服、务、器
3 小结
- 创建文档(JSON/Map)
创建文档数据有2种方法,一种是JSON方式,另外一种是基于Map方式
- ES数据搜索
根据ID搜索、搜索全部不走索引 字符串搜索、词条搜索、通配符搜索走索引