教你快速入门ElasticSearch,超详细简单~
一. 初探ElasticSearch
1.1 什么是ElasticSearch?
- ElasticSearch,简称为ES,它是一个开源的高扩展的分布式全文检索硬气,它可以近乎实时的存储、检索数据;
- 它的扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用java开发并使用Lucene作为其核心来实现所有索引和搜索的功能。
- 它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
1.2 它与Solr的对比?
- Solr利用Zookeeper进行分布式管理,而ElasticSearch自身带有分布式协调管理的功能。
- Solr支持更多格式的数据,而ElasticSearch仅支持json文件格式。
- Solr官方提供的功能更多,而ElasticSearch本身更注重于核心功能,高级功能多依靠第三方插件提供。
- Solr在传统的搜索应用中表现好于ElasticSearch,但在实时搜索应用时效率明显低于ElasticSearch。
1.3 安装ElasticSearch
- ElasticSearch下载地址:下载地址
- bin目录中有
windows
和linux
下的启动命令。 - 启动(运行环境首先嘚要安装java,然后版本必须大于等于JDK1.8,它是基于Java运行的。)点击bin目录下的
elasticsearch
图标,即可执行成功,如果在linux环境下,则选择linux下的sh运行文件。如图所示:
- 启动成功过后,9300端口是Api对服务器的管理端口,9200是restful,http形式的端口。启动成功后如图所示:
- 页面进行访问:
1.4 安装ES的图形化界面插件
- 介绍:
- 安装步骤:
- 下载head插件:https://github.com/mobz/elasticsearch-head
- 安装node.js,可参考博主之前的文章或者网上参考教程。(步骤为:官网下载node.js,然后按提示安装,输入
node -v
查看版本检查是否安装成功。)它是运行在node.js上的,所以我们需要安装它。
- 将grunt安装为全局命令,Grunt是基于Node.js的项目构建工具,在cmd控制台输入如下执行命令:
npm install -g grunt-cli
- 进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:
npm install
grunt server
head是指的刚才下载的head插件。
- 启动成功后如图所示:
- 网页访问如图所示:
- 因为两个端口涉及到了跨域,在config/elasticsearch.yml中添加跨域配置:
- 添加好跨域后,重新启动es,然后在head上重新点击连接,图形界面安装完成。
1.5 ElasticSearch相关概念(术语)
- 概述:
- ElasticSearch核心概念:
- 索引Index:
- 类型type:
- 字段Field:
- 映射mapping
- 文档document
- 接近实时NRT
- 集群cluster:
- 节点node:
- 一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于ElasticSearch集群中的哪些节点。
- 一个节点可以通过配置集群的名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做"elasticsearch"的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够互相发现彼此,它们将会自动地形成并加入到一个叫做elasticsearch的集群中。
- 在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做elasticsearch的集群。
- 分片和复制shards&replicas
二. 基于ElasticSearch常用功能演示
2.1 创建索引
-
使用图形化界面创建索引:
- 创建如图所示:
- 创建成功后,点击概览即可查看已创建成功的索引:
- 使用查询语句创建:
- 创建如图所示:
-
使用postman创建名称为:
blog
的索引:- 图示:
- 创建成功后,点击概览,发现新建的blog索引已创建成功:
- 图示:
-
使用
mapping
创建带field的索引:
-
创建索引后设置Mapping信息(创建type后为指定type设置mapping):
2.2 删除索引
2.3 添加文档
2.4 删除文档
- 请求方式为
delete
,然后url中提供索引
、类型
、文档id
,即可删除。图示如下:
2.5 修改文档
- 图示:
修改文档跟新增的方式一样。如果此_id数据已存在,则会先删除老数据,然后再添加新的数据。如果此_id不存在,则会进行新增。
2.6 根据文档id查询文档
指定了index/type/field,所以能够查询到指定的文档数据。
2.7 根据关键词查询文档
- 查询:
- 查看返回结果:
2.8 查询文档-queryString查询
2.9 使用head插件查询
2.10 分词器
-
标准分词器:
-
如何解决?
-
IK分词器简介:
- 图示:
- 安装步骤:
- 网上下载Ik分词器,然后解压缩,放到es中的plugin文件夹中,然后重启es服务即可。
- 图示:
-
使用IK分词器效果:
- 概述:IK提供了两个分词算法ik_smart和ik_max_word.其中ik_smart为最少切分,ik_max_word为最细粒度切分。
- 最小切分:在浏览器中输入地址:
http://127.0.0.1:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员
分词结果为: 我,是,程序,程序员
- 最细粒度切分:在浏览器中输入地址:
http://127.0.0.1:9200/_analyze?analyzer=ik_max_word&text=我是程序员
分词结果为: 我,是,程序,程序员,员。 说明它的拆分结果更细,分词结果更多。
-
ik分词器的使用:
三. ElasticSearch集群
3.1 ElasticSearch架构及说明
- 概述:
- 集群架构说明:
3.2 集群架构搭建
- 准备工作:
- 将我们单机版的es改名为elasticsearch-cluster,然后配置好ik分词器,cors跨域等配置,再复制三份,分别为如图所示::
> - 修改elasticsearch-cluster/node*/config/elasticsearch.yml文件:
- node1节点:
- node2节点:
- node3节点:
主要配置了节点名称和端口号。
- node1节点:
- 分别各个节点启动,然后会自动连接起来变成集群,连接任意一个端口进行验证:
- 创建索引库:
- 创建索引:
- 查询分片验证:
- 创建索引:
四、使用java客户端简单操作es
4.1 使用java客户端完成创建索引库及文档的添加
- 大致步骤:
- 步骤如下:
-
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
- 大致步骤:
- 具体测试代码:(在上面的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对象,所以我们将这个操作进行提出来:
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)); } }
- 创建文档:
@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(); }
- 我们每次都要创建Settings、Client对象,所以我们将这个操作进行提出来:
- 创建文档的第二种方式(使用对象的方式进行创建):
五. 使用java客户端实现对es的搜索功能
5.1 根据id查询
- 大致步骤:
- 代码演示:
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"));
}
}
@L_404[email protected] 分页查询
- 大致步骤:
- 代码演示:
5.5 查询结果高亮显示
- 大致步骤:
- 代码演示:
六、使用Spring Data ElasticSearch操作ES
5.1 完成Spring Data ElasticSearch的环境搭建
-
什么是Spring Data?
-
什么是Spring Data ElasticSearch?
-
搭建步骤:
5.4 完成Spring Data ElasticSearch的基本增删改查操作
5.5 自定义查询方法
自定义查询方法,我们需要根据SpringDataES 的命名规则来命名,这样我们定义了接口就会自动实现功能。如果我们没有实现分页的话,无论es中匹配的有多少条数据,最多也只会默认给我们返回10条。如果需要指定分页,可以使用上面的带分页查询方式。
5.6 使用NativeSearchQuery查询
-
直接使用
章节5.5
中的查询方式,查询的内容比如:“我是程序员”,那么它不会再将结果进行分词,所以匹配的结果是我是程序员这个原子词汇。如果要对查询条件再分词,比如我是程序员分词,能够匹配到:我、是、程序、程序员、员的所有数据,我们需要使用queryString方式进行查询。 -
大致步骤:
-
代码演示:
@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)) }
稍微麻烦点,但是功能更强,灵活性更高
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。