IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> ElasticSearch -> 正文阅读

[大数据]ElasticSearch

ElasticSearch 简介

ElasticSearch 简称 ES,是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器上,处理PB级别的数据。ES也是用Java开发并使用Lucene作为其核心实现所有的索引和搜索的功能,但是他的目的是通过简单的 RestFul API来隐藏Lucene的复杂性,让全文搜索变得更简单

2016年1月,ElasticSearch 超过 Solr,成为排名第一的搜索引擎应用

ElasticSearch 和 Solr 的区别
ElasticSearch 用于 全文搜索、结构化搜索、分析

Solr 是 Apache 下的一个顶级开源项目,采用Java开发,基于 Lucene 的全文搜索服务器,Solr 提供了比 Lucene 更为丰富的查询语言,同时实现了可配置,可扩展,并对索引、搜索性能进行了优化

Solr 可以独立运行在 Jetty 等Servlet容器中,

Solr 是一个独立的企业级搜索应用服务器,实际上就是封装了 Lucene,对外提供类似于 Web-service的API接口,用户可以通过http请求,想搜索引擎服务器提交一定格式的文件,生成索引,也可以通过提出查找请求,得到结果

ElasticSearch vs Solr:

  • ES 基本是开箱即用,解压就可以使用,非常简单,Solr 的使用略复杂
  • Solr 利用 Zookeeper 进行分布式管理,ElasticSearch 自身带有分布式协调管理功能
  • Solr 支持更多格式的数据,比如,JSON,XML,CSV ,ElasticSearch 仅支持 JSON 文件格式
  • Solr 官网提供的功能更多,ElasticSearch 本身更专注核心功能,高级功能多由第三方插件提供,如图形化界面需要 kibana 友好支持
  • Solr 查询快,但更新搜索引擎慢,适合用于电商扥个查询多的应用
  • ES 建立搜索引擎模块,查询慢,即时性查询快,适用于facebook、新浪等实时搜索应用
  • Solr 是传统搜索应用的有力解决方案,但ElasticSearch 更适用于新型的实时型搜索应用
  • Solr比较成熟,有一个更大、更成熟的用户、开发贡献社区,而ElasticSearch 相对开发维护者较少,更新又太快,学习使用成本较高
  • ElasticSearch 是未来的使用趋势

ElasticSearch 安装

软件安装

最低要求 JDK 1.8,maven,web 项目需要有前端环境 node.js相关

官网(比较慢):https://www.elastic.co/cn/downloads/?elektra=home&storm=hero

ElasticSearch: https://mirrors.huaweicloud.com/elasticsearch/?C=N&O=D

logstash: https://mirrors.huaweicloud.com/logstash/?C=N&O=D

可视化界面:elasticsearch-head.https://github.com/mobz/elasticsearch-head

kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D

ik分词器 https://github.com/medcl/elasticsearch-analysis-ik

实际生产环境使用 Linux 版本,这里我们学习使用,Windows版本即可

window 下安装!

1、解压就可以使用了!
在这里插入图片描述

2、熟悉目录!

bin 启动文件

config 配置文件

log4j2 日志配置文件

jvm.options java 虚拟机相关的配置

elasticsearch.yml elasticsearch 的配置文件! 默认 9200 端口! 跨域!

lib 相关jar包

logs 日志!

modules 功能模块

plugins 插件!

jvm.options java 虚拟机相关的配置

img

3、启动,访问 9200;
在这里插入图片描述
在这里插入图片描述

4、访问测试!

img

安装可视化界面 es head 的插件

没有前端基础的,先去看我的 Vue,把基本的环境安装完毕!

1、下载地址:https://github.com/mobz/elasticsearch-head/

2、启动

文档主目录下cmd命令

npm install
npm run start

img

3、连接测试发现,存在跨域问题:配置 es

http://localhost:9100

在这里插入图片描述
配置

在这里插入图片描述

在这里插入图片描述

http.cors.enabled: true
http.cors.allow-origin: "*"

4、重启 es 服务器,然后再次连接
在这里插入图片描述

安装 Kibana

Kibana 是一个针对 Elasticsearch 的开源分析及可视化平台,用来搜索、查看交互存储在 Elasticsearch 索引中的数据。使用 Kibana,可以通过各种图表进行高级数据分析及展示。Kibana 让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示 Elasticsearch 查询动态。设置 Kibana 非常简单。无需编码或者额外的基础架构,几分钟内就可以完成 Kibana 安装并启动 Elasticsearch 索引监测。

官网:https://www.elastic.co/cn/kibana

Kibana 版本要和 Es 一致!

下载完毕后,解压也需要一些时间!是一个标准的工程!

好处:ELK 基本上都是拆箱即用!

解压后 Kibana 已经包含了依赖,且有bin目录,进入bin目录,右键管理员运行 kibana.bat 文件,启动比较慢,

访问页面测试可以使用 Postman、curl、elasticsearch-head、这里我们就使用 kibana

以后的搜索测试 请求语句 可以写在这里,通过kibana 来向搜索引擎 elasticsearch 进行查询请求

访问测试 http://localhost:5601

kibana 默认英文,如何汉化?

我们修改 kibana 核心配置文件,在 kibana-7.6.1-windows-x86_64\config 目录下,kibana.yml 添加国际化配置,默认是英文

末尾添加即可   i18n.locale: "zh-CN"

ElasticSearch 使用详解

1.ES 核心概念

  1. 索引
  2. 字段类型(mapping)
  3. 文档(documents)

集群,节点,索引,类型,文档,分片,映射是什么?

elasticsearch是面向文档,关系型数据库和elasticsearch客观的对比!一切都是json

Relational DBElasticsearch
数据库(database)索引(indices)
表(tables)types
行(rows)documents
字段(columns)fields

2.ik分词器

什么是IK分词器 ?

分词:

  • 即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词。
  • 比如“我爱狂神”会被分为"我",“爱”,“狂”,“神” ,这显然是不符合要求的,所以我们需要安装中文分词器ik来解决这个问题。

如果要使用中文,建议使用ik分词器!

IK提供了两个分词算法:

  • ik_ smart和ik_ max_ word
  • ik_ smart为最少切分,ik_ max_ _word为最细粒度划分!

下载

  • 下载:https://github.com/medcl/elasticsearch-analysis-ik
  • 版本不全到这里找:https://elasticsearch.cn/download/

下载完毕后,直接放到目录中 elasticsearch\elasticsearch-7.6.1\plugins 即可,注意将分词器的目录名改为 ik

重启 elasticsearch,在启动过程中可以看到,elasticsearch 加载了 ik 分词器

重启失败原因:

  • elasticsearch 与 ik 分词器版本一定要完全对应上,只对应大版本号不够
  • 如何查看 ik版本号,查看目录下 plugin-descriptor.properties 文件,

img

  • 解压后,压缩包删除,分词器目录取名ik
  • kabana 和 head 最好也关掉,一起重启

如何确认 elasticsearch 启动成功加载插件?启动 elasticsearch bin 目录中提供的工具 elasticsearch-plugin.bat

进入 elasticsearch bin 目录启动命令行 elasticsearch-plugin list
img

表示加载成功

测试使用

进入 kibana 界面 Dev Tools 菜单,发起请求,选择分词算法

【ik_smart】(最少切分)测试:

GET _analyze
{
  "analyzer": "ik_smart",
  "text": "我是社会主义接班人"
}

【ik_max_word】(最细粒度划分)测试

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "我是社会主义接班人"
}

ik分词器如何增加配置

进入分词器目录 elasticsearch\elasticsearch-7.6.1\plugins\ik\config ,这个目录包含了各种字典,

我们可以创建的自己的字典,然后配置到 IKAnalyzer.cfg.xml 文件中

新建字典文件,比如,swy.dic(就在config目录下),编辑内容,比如添加

泥萌好
swy

这样,泥萌好,swy,就会默认成为一个词,被ik分词器识别

在配置文件 IKAnalyzer.cfg.xml 中,添加

<entry key="ext_dict">swy.dic</entry>

重启es,查看启动日志可以看到,我们的新的分词字典已经被加载

在这里插入图片描述

3.关于索引的基本操作

格式 PUT /索引名/类型名/文档id

注意,PUT 后面有空格

创建文档

  1. 添加数据
PUT /kuangshen/user/1
{
	"name": "狂神说",
	"age": 23,
	"desc": "一顿操作猛如虎,一看工资2500",
	"tags": ["技术宅","温暖","直男"]
}

2、获取数据 GET

GET  kuangshen/user/1

3、更新数据 PUT

PUT /kuangshen/user/3
{
	"name": "李四233",
	"age": 30,
	"desc": "逍遥自在",
	"tags": ["靓仔","大餐","编程"]
}

4、POST _update , 推荐使用这种更新方式!

POST /kuangshen/_update/1
{
  "doc": {
    "name": "狂神说Java"
  }
}

简单地搜索!

GET kuangshen/user/1

简答的条件查询,可以根据默认的映射规则,产生基本的查询!

GET  kuangshen/user/_search?q=name:狂神说Java

4.复杂操作搜索 select

复杂操作查询:select(排序,分页,高亮,模糊查询,精准查询)

//查询具体的参数使用 json  
//1.条件查询

GET  kuangshen/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  }
}

img

//结果过滤,查询并输出的结果不需要那么多字段

GET  kuangshen/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  },
  "_source": ["name","desc"]
}

img

//3.排序操作,sort 表示通过哪个字段排序
GET  kuangshen/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}
//4.分页查询,需要包含从哪里开始,以及页面大小
//数据下标从0开始,与其他数据库是一样的
GET  kuangshen/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 1
}
//5.多条件查询,使用布尔值查询
//must(相当于and),should(相当于or),must_not(不等于xxx条件)

GET  kuangshen/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "狂神说"
          }
        },{
          "match": {
            "age": 3
          }
        }
      ]
    }
  }
}

GET  kuangshen/user/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "狂神说"
          }
        },{
          "match": {
            "age": 3
          }
        }
      ]
    }
  }
}

GET  kuangshen/user/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "age": 23
          }
        }
      ]
    }
  }
}

过滤器 filter

//6.过滤器 filter,
//这里附加了范围  gt-大于 gte-大于等于 lt-小于 lte-小于等于!
GET  kuangshen/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "狂神说"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 10,
            "lte": 30
          }
        }
      }
    }
  }
}
//7.匹配多个条件,tags,比如根据性格标签,可以计算出权重
//多个条件使用空格分开即可

GET swy/user/_search
{
  "query": {
    "match": {
      "tags": "白 富 美"
    }
  }
}

8.精确查询

term查询是直接通过倒排索引指定的词条进程精确查找的

关于分词

  • term,直接查询精确的
  • match,会使用分词器解析,先分析文档,再通过分析的文档进行查询

关于两个类型

  • text类型可以被分词解析
  • keyword不会被分词解析
举个例子,创建索引
添加数据
改变id,以及属性参数,添加多条数据
当成 keyword 方式分词,是看做一个整体
standard 普通方式,普通分词处理,当然我们也可以使用中文分词
开始查询
当我们搜索 name属性(text类型)时,由于这种数据默认可以被分词器解析,所以,即使我们搜索部分单词,也可以找到完整相关数据
当我们搜素 desc 属性(keyword类型)时,整个属性值被看做一个整体,搜索单个词无法找到,只有搜索整体才有结果
结论:keyword 属性的字段不会分词器解析,设置属性的时候需要注意
//9.多个值匹配的精确查询

//先添加一些数据,
PUT testdb/_doc/3
{
  "t1": "22",
  "t2": "2020-04-06"
}
PUT testdb/_doc/4
{
  "t1": "33",
  "t2": "2020-04-07"
}
//开始查询
GET testdb/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "t1": "22"
          }
        },
        {
          "term": {
            "t1": "33"
          }
        }
      ]
    }
  }
}
//10.高亮查询
//搜索的结果中包含搜索词条的部分,用高亮显示
//查询的时候,添加高亮属性,并设置需要高亮的字段
//搜索相关的结果,会被自动加上标签

GET swy/user/_search
{
  "query": {
    "match": {
      "name": "swy"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

小结:

  • 匹配
  • 按条件匹配
  • 精确匹配
  • 区间范围匹配
  • 匹配字段过滤
  • 多条件匹配
  • 高亮查询

这些 MySQL 也可以做,只不过效率比较低

尤其在海量数据的情况下,es的性能优势非常明显

SpringBoot 集成 ElasticSearch

项目准备

创建maven项目作为父项目,删除多余文件,创建子模块springboot项目,添加项目依赖

img

//检查springboot-starter下载的依赖,es依赖版本是否与我们安装的版本一致,如果不一致,将连接不上,一定要确保一致
//添加与本地版本相匹配的依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.6.1</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.70</version>
</dependency>

项目初始化

添加配置类,注入bean

@Configuration
public class ElasticSearchClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }
}

API 索引操作

使用前确保,elasticsearch 已经启动

编写测试类,有了之前通过 kibana 的使用,我们现在开始转为使用Java API进行操作

@SpringBootTest
class EsApiApplicationTests {

	@Autowired
	@Qualifier("restHighLevelClient")
	private RestHighLevelClient client;

	// 测试索引的创建
	@Test
	void testCreateIndex() throws IOException {
		// 1.创建索引的请求
		CreateIndexRequest request = new CreateIndexRequest("swy_index");
		// 2.客户端执行请求,请求后获得响应
		CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
		System.out.println(response);
	}
    
    // 测试索引是否存在
	@Test
	void testExistIndex() throws IOException {
		// 1.创建索引的请求
		GetIndexRequest request = new GetIndexRequest("swy_index");
		// 2.客户端执行请求,请求后获得响应
		boolean exist =  client.indices().exists(request, RequestOptions.DEFAULT);
		System.out.println("测试索引是否存在-----"+exist);
	}

    // 删除索引
	@Test
	void testDeleteIndex() throws IOException {
		DeleteIndexRequest request = new DeleteIndexRequest("swy_index");
		AcknowledgedResponse delete = client.indices().delete(request,RequestOptions.DEFAULT);
		System.out.println("删除索引--------"+delete.isAcknowledged());
	} 
    
}

API 文档操作

创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
    private String name;
    private int age;
}

编写测试类

@SpringBootTest
class EsApiApplicationTests {

	@Autowired
	@Qualifier("restHighLevelClient")
	private RestHighLevelClient client;

	// 测试添加文档
	@Test
	void testAddDocument() throws IOException {
		User user = new User("swy",18);
		IndexRequest request = new IndexRequest("swy_index");
		request.id("1");
		// 设置超时时间
		request.timeout("1s");
		// 将数据放到json字符串
		request.source(JSON.toJSONString(user), XContentType.JSON);
		// 客户端发送请求,获取响应结果
		IndexResponse response = client.index(request,RequestOptions.DEFAULT);
		System.out.println("添加文档-------"+response.toString());
		System.out.println("返回状态-------"+response.status());
	}

    // 测试文档是否存在
	@Test
	void testExistDocument() throws IOException {
		// 测试文档的 没有index
		GetRequest request= new GetRequest("swy_index","1");
		// 没有indices()了
		boolean exist = client.exists(request, RequestOptions.DEFAULT);
		System.out.println("测试文档是否存在-----"+exist);
	}

    // 测试获取文档
	@Test
	void testGetDocument() throws IOException {
		GetRequest request= new GetRequest("swy_index","1");
		GetResponse response = client.get(request, RequestOptions.DEFAULT);
		System.out.println("测试获取文档-----"+response.getSourceAsString());
		System.out.println("测试获取文档-----"+response);
	}

    // 测试修改文档
	@Test
	void testUpdateDocument() throws IOException {
		User user = new User("托克马克", 200);
		// 修改是id为1的
		UpdateRequest request= new UpdateRequest("swy_index","1");
		request.timeout("1s");
		request.doc(JSON.toJSONString(user),XContentType.JSON);
		UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
		System.out.println("测试修改文档-----"+response);
		System.out.println("测试修改文档-----"+response.status());
	}

    // 测试删除文档
	@Test
	void testDeleteDocument() throws IOException {
		DeleteRequest request= new DeleteRequest("swy_index","1");
		request.timeout("1s");
		DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
		System.out.println("测试删除文档------"+response.status());
	}

    //测试批量添加文档
	@Test
	void testBulkAddDocument() throws IOException {
		ArrayList<User> userlist = new ArrayList<User>();
		userlist.add(new User("swy1",5));
		userlist.add(new User("swy2",6));
		userlist.add(new User("swy3",40));
		userlist.add(new User("swy4",25));
		userlist.add(new User("swy5",15));
		userlist.add(new User("swy6",35));
		// 批量操作的Request
		BulkRequest request = new BulkRequest();
		request.timeout("1s");
		// 批量处理请求
		for (int i = 0; i < userlist.size(); i++) {
			request.add(
					new IndexRequest("swy_index")
							.id(""+(i+1))
							.source(JSON.toJSONString(userlist.get(i)),XContentType.JSON)
			);
		}
		BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
		// response.hasFailures()是否是失败的
		System.out.println("测试批量添加文档-----"+response.hasFailures());
	}
    
//查询操作
    //SearchRequest 搜索请求
    //SearchSourceBuilder 请求条件构造,
    //highlighter 设置高亮
    //TermQueryBuilder 精确查询
    //MatchAllQueryBuilder 匹配全部查询
    //xxxQueryBuilder 对应了我们刚才看到的所有命令
    
// 测试查询文档
	@Test
	void testSearchDocument() throws IOException {
		SearchRequest request = new SearchRequest("swy_index");
		// 构建搜索条件
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		// 设置了高亮
		sourceBuilder.highlighter();
		// term name为swy1的
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "swy1");
		// 匹配所有
		// MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
		sourceBuilder.query(termQueryBuilder);
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		request.source(sourceBuilder);
		SearchResponse response = client.search(request, RequestOptions.DEFAULT);
		// 查询结果都封装在hit中
		System.out.println("测试查询文档-----" + JSON.toJSONString(response.getHits()));
		System.out.println("=====================");
		for (SearchHit documentFields : response.getHits().getHits()) {
			System.out.println("测试查询文档--遍历参数--" + documentFields.getSourceAsMap());
		}
	}
    
}
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:33:51  更:2021-07-24 11:35:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 4:22:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码