数据库的select * from user where name like 'xxx'
:1. 不走索引,数据库量很大时,查询慢。2. 往往会返回大量的数据。3.用户输入的内容可能并不准确。
Elasticsearch优势
Elasticsearch是面向文档的一种数据库,这意味着其不再需要行列式的表格字段约束。
ES会存储整个构造好的数据或文档,然而不仅仅是储存数据,这使得文档中每个数据可以被标识,进而可以被检索。在ES中,执行index,search,sort或过滤文档等操作都不是传统意义上的行列式的数据。
ES从根本上对数据的不同思考方式也正是他能应对复杂数据结构的全文检索的原因之一。
Elastic Search 中代码几乎全部是为搜索服务器服务的。真正处理倒排索引、具体搜索算法的,则Lucene 核心引擎。
Kibana是一个针对Elasticsearch的开源分析及可视化平台 ,用来搜索、查看交互存储在Elasticsearch索引中的数据。 使用Kibana,可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板( dashboard )实时显示Elasticsearch查询动态。设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动Elasticsearch索引监测。
Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。
下载:https://www.elastic.co/cn/downloads/elasticsearch
# docker安装
sudo apt install docker
# 拉取
docker pull elasticsearch:7.14.2
# 查看镜像是否拉取到本地
docker images
# 运行
# -d : 后台运行
# -p : 指定宿主机与docker启动容器的端口映射
# --name : 为ES容器别名
# -e : 指定为单节点集群模式
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" elasticsearch:7.14.2
# 访问
curl http://localhost:9200/
ES_JAVA_OPTS
:配置JVM参数,会覆盖JAVA_OPTS中配置的相同参数。最主要的作用是指定 -Xmx 最大堆大小和 -Xms 最小堆大小(分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半)。
-v
:挂载数据卷
--privileged=true
:让docker有root权限启动容器
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /home/xxx/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/xxx/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/xxx/elasticsearch/plugins:/usr/share/elasticsearch/plugins elasticsearch:7.14.2
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" \
-v /home/xxx/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
elasticsearch:7.14.2
# 拉取(与ES版本保持一致)
docker pull kibana:7.14.2
# 运行
# -e : 指定环境变量配置, 提供汉化
# --link : 建立两个容器之间的关联, kibana 关联到 es
docker run -d --name kibana --link elasticsearch:elasticsearch \
-e "I18N_LOCALE=zh-CN" -p 5601:5601 kibana:7.14.2
# 查看日志
docker logs kibana
# 访问
# http://localhost:5601/app/dev_tools#/console
进入Kibana首页选择DevTools(URL: http://localhost:5601/app/kibana#/dev_tools/console)即可输入命令向ES发出请求。
文件名 | 备注 |
---|---|
data | 索引数据 |
config | elastic-search的全局设置和用户具体设置(JVM,数据路径,日志路径、端口设置等) |
bin | 可执行文件,启动elasticsearch |
jdk.app | 自带的JDK |
plugins | 插件(第三方的分词器等) |
modules | elastic search自带的一些模块 |
lib | 相关jar包 |
logs | 日志 |
config:
文件名 | 备注 |
---|---|
log4j2.properties | 日志配置文件 |
jvm.options java | 虚拟机配置文件 |
elasticsearch.yml | ES配置文件(默认端口:9200) |
名称 | 释义 | 备注 |
---|---|---|
Index | 文档在哪个索引存放: 相当于数据库db(Table) | |
Document | 数据库的一行记录row | Elasticsearch是面向文档的,使用JSON作为序列化格式存储整个对象。 |
Type(废除,默认类型 _doc 代替) | 文档对象类型:相当于数据库Table | 一个Index下支持多个Type =》Table Type只是Index中的虚拟逻辑分组,不同的Type应该有相似的结构。 |
Field | 数据库的Column | |
Mapping | 数据库的Schema | |
_id | 文档唯一标识 | |
_version | 数据版本 | |
DSL | ES读取API |
Elasticsearch(一般为集群)中可以包含多个索引(对应数据库) ,每个索引中可以包含多个类型(对应表) ,每个类型下又包含多个文档(对应行),每个文档中又包含多个字段(对应列)。
ElasticSearch 是分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个实例。单个实例称为一个节点(node),一组节点构成一个集群(cluster)。
分片是底层的工作单元,文档保存在分片内,分片又被分配到集群内的各个节点里,每个分片仅保存全部数据的一部分。
一个集群是一些运行 Elastic Search 的节点服务器(node)的总称。
一个Elasticsearch集群有多个Elasticsearch节点:一个主节点Master Node,多个从节点。如果主节点挂了,会选举出一个新的主节点。
一个集群中,可能包含一个或多个节点。这些节点受到集群的管理。你可以向一个集群中增加或者删除一些节点(扩容或者减容),也可以查询节点的信息(比如这个节点的 CPU 使用状况如何等等)。
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html
分片(各节点并行,提高系统吞吐量):一个Index(数据库表)的数据我们可以分发到不同的Node上进行存储(1个Index、4个Node :设置4个分片)。
数据写入到主分片,副本分片会复制主分片的数据,读取的时候主分片和副本分片都可以读。
如果某个节点挂了,Master Node就会把对应的副本分片提拔为主分片,数据就不会丢。
如果一个Index的数据量太大,只有一个分片,那只会在一个节点上存储,随着数据量的增长,一个节点未必能把一个Index存储下来。
多个分片,在写入或查询的时候就可以并行操作(从各个节点中读写数据,提高吞吐量)。
客户端写入一条数据,Elasticsearch集群由节点来处理这次请求。
集群上的每个节点都是coordinating node(协调节点),协调节点表明这个节点可以做路由(请求转发)。
shard = hash(document_id) %(num_of_primary_shards)
主分片写完后,会将数据并行发送到副本集节点上,等到所有的节点写入成功就返回ack给协调节点,协调节点返回ack给客户端,完成一次的写入。
给对应的doc记录打上【.del】标识。
足够多的segement文件存在时会合并成一个segement文件。合并时,把带有delete状态的doc给物理删除掉。
根据ID查询doc(实时)
1.1 检索内存的Translog文件
1.2 检索硬盘的Translog文件
1.3 检索硬盘的Segement文件
根据query(搜索词)去查询匹配的doc(写入后1s才能查,segement文件是每隔一秒才生成一次的)
2.1 同时查询内存和硬盘的Segement文件
public TopDocs search(Query query, int n);
public Document doc(int docID);
Character Filters(文本过滤器,去除HTML)
Tokenizer(按照规则切分,比如空格)
TokenFilter(将切分后的词进行处理,比如转成小写)
数据类型 | |
---|---|
字符串类型 | text、keyword |
数值类型 | long、integer、short、byte、double、float、half float、scaled float |
日期类型 | date |
布尔值类型 | boolean |
二进制类型 | binary |
curl -X
GET
、 POST
、 PUT
、 HEAD
或者 DELETE
。# 计算集群中文档的数量
curl -X GET 'http://localhost:9200/_count?pretty' -d '
{
"query": {
"match_all": {}
}
}
'
# Kibana中
GET /_count?pretty
{
"query": {
"match_all": {}
}
}
PUT\POST /索引名/类型名(新版本逐步废弃,默认类型_doc代替)/文档ID
{
请求体
}
往索引为 db(SQL数据库), 类型为 user(SQL Table) 的数据库中插入一条 id 为 1(SQL row?) 的一条数据(拥有 username/password/age 三个属性的实体)。
POST /db/user/1
{
"username": "wmyskxz1",
"password": "123456",
"age": "22"
}
PUT /test3/_doc/1
{
"name": "流柚",
"age": 18,
"birth": "1999-10-10"
}
PS:PUT如果漏了一些信息,原始信息就会丢失,故现在一般使用POST来更新索引。
PUT /test2
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
GET test2
DELETE /db/user/1
PUT /db/user/1
{
"username": "wmyskxz3",
"password": "123456",
"age": "22"
}
POST /test3/_doc/1/_update
{
"doc":{
"name" : "post修改,version不会加一",
"age" : 2
}
}
GET /db/user/1
GET <index>/<type>/_search
GET /test3/_doc/_search?q=name:流柚
GET /blog/user/_search
{
"query":{
"match":{
"name":"流"
}
},
"_source": ["name","desc"],
"sort": [
{
"age": {
"order": "asc"
}
}
],
"from": 0,
"size": 1
}
GET /blog/user/_search
{
"query":{
"bool": {
"must": [
{
"match":{
"sex": "女"
}
},
{
"match": {
"name": "流"
}
}
],
"filter": {
"range": {
"age": {
"gte": 1,
"lte": 100
}
}
}
}
}
}
多关键字查(空格隔开) :match 会使用分词器解析(先分析文档,然后进行查询)
GET /blog/user/_search
{
"query":{
"match":{
"name":"流 水"
}
}
}
term 直接通过 倒排索引 指定词条查询
GET /blog/user/_search
{
"query":{
"term":{
"name":"流 水"
}
}
}
GET blog/user/_search
{
"query": {
"match": {
"name":"流"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
GET blog/user/_search
{
"query": {
"match": {
"name":"流"
}
},
"highlight": {
"pre_tags": ""
,
"post_tags": "",
"fields": {
"name": {}
}
}
}
ElasticSearch自己基于JSON的域特定语言,可以在其中表达查询和过滤器。
GET /_search
{
"query": {
//Query DSL here
"query_string": {
"query": "kill"
}
}
}
命令行请求:
curl -X GET 'http://localhost:9200/db/user/_search?q=kill&pretty'
或
curl -X GET 'http://localhost:9200/db/user/_search?pretty' -d '
{
"query" : {
"query_string": {
"query": "kill"
}
}
}
'
fields
fields:可用于指定要搜索的字段列表。如果不使用“fields”字段,ElasticSearch查询将默认自动生成的名为 “_all” 的特殊字段,来基于所有文档中的各个字段匹配搜索。
GET /_search
{
"query": {
"query_string": {
"query": "ford",
"fields": [
"title"
]
}
}
}
filtered
(废除)query
和 filter
。GET /_search
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "drama"
}
},
"filter": {
# //Filter to apply to the query
"term": {"year": 1962}
}
}
}
}
条件过滤器:term
GET /_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"term": {
"year": 1962
}
}
}
}
}
GET /_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"year": 1962
}
}
}
}
}
Bool查询对应Lucene中的BooleanQuery,它由一个或者多个子句组成,每个子句都有特定的类型。
text:支持分词、全文检索,支持模糊、精确查询,不支持聚合、排序操作。最大支持的字符长度无限制,适合大字段存储。
keyword:不进行分词,直接索引,支持模糊、精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。
GET _analyze
{
"analyzer": "keyword",
"text": ["测试liu"]
}// keyword不会分词,即 测试liu
GET _analyze
{
"analyzer": "standard",
"text": ["测试liu"]
}// 分为 测 试 liu
GET _analyze
{
"analyzer":"ik_max_word",
"text": ["测试liu"]
}// 分为 测试 liu
GET _cat/indices
GET _cat/aliases
GET _cat/allocation
GET _cat/count
GET _cat/fielddata
GET _cat/health
GET _cat/indices
GET _cat/master
GET _cat/nodeattrs
GET _cat/nodes
GET _cat/pending_tasks
GET _cat/plugins
GET _cat/recovery
GET _cat/repositories
GET _cat/segments
GET _cat/shards
GET _cat/snapshots
GET _cat/tasks
GET _cat/templates
GET _cat/thread_pool
GET _cluster/health
GET /_cat/nodes
、GET /_cat/nodes?v
(?v 让kibana 输出逻辑模式即verbose模式的首字母)配置es,打开elasticsearch.yml文件,在最后一行加入(注意yalm语法,冒号后要加一个空格)
http.cors.enabled: true
http.cors.allow-origin: "*"
重启es。
在Kibana目录下的config中修改Kibana.yml文件,最后一行加上
i18n.locale: "zh-CN"
重启。
docker 安装 elasticsearch & kibana, 杜绝报错
elasticsearch初学终极教程 - 第二章: 把Elastic Search在本地跑起来
什么是 Elasticsearch?一篇搞懂
终于有人把Elasticsearch原理讲透了!
搜索引擎入门
教程
官方教程
ElasticSearch 快速上手学习入门教程
书
Elastic社区
集群配置
【狂神说Java】ElasticSearch7.6.x最新完整教程通俗易懂
狂神说笔记之ElasticSearch