elasticsearch基本入门
elasticsearch
1.索引
elasticsearch中数据的逻辑存储,相当于关系数据库中的数据库。索引由一个或多个luncene索引构成。
创建索引只能在主分片进行
创建索引过程:
文档
数据实体,文档由字段构成、字段可以包含一个或多个值(这种情况下,被称为多值字段即文档中存在多个重名字段),文档没有固定模式或强制结构
映射
文档写入前需要先分析,通过设置参数来决定如何将输入文笔分割为此条,哪些过滤调,或哪些附加处理是有必要被调用的(去除HTML标签)。还有例如排序时所需的字段内容信息就是映的功能。
节点
单个es服务实例称为节点(node)。
集群
当数据量或者查询压力超过单机负载时,需要多个节点来协同处理,素有这些阶段主城的系统称为集群(cluster)。
分片
集群允许系统存储的数据总量超过单机容量。为满足这个需求,es将数据分散部到多个物理lucene索引上。这些luncene索引称为分片(shard),而散布的过程叫做分片处理starding
副本
副本解决访问压力过大时单机无法处理请求的问题。思路就是为每个分片创建冗余的副本,处理查询是可以把副本用作最初的主分片(primary shard),副本数量可以调整。
网关
在es工作过程中,收集集群状态、索引设置的各种信息,在网关中持久化。
启动过程
使用广播技术(也可配置单播)来发现同一个集群中的其他节点(配置文件的集群名称)
集群会有一个阶段被选为管理节点(master node),这个过程es内部会自动处理
管理节点读取集群状态信息,必要时进行恢复处理,在该阶段,管理节点会检查所有索引分片并界定那些分片用于主分片,集群进入黄色状态。
意味着集群可以执行查询,但系统吞吐量以及各种可能的情况是位置的(简单的理解为所有的主分片已经分配出去了,而副本没有)接下来是寻找到冗余的分片并用作副本。如果谋改革主分片的副本数量过少,管理节点将基于某个主分片创建分片和副本。之后集群进入绿色状态
故障检查
集群正常工作时,管理节点会监控所有可用节点,如果任何节点在预定的超时时间内没有响应,则认为该节点已经断开,然后启动错误流程重新平衡分片。也就是主分片断掉之后,由副本中产生,新分片和副本的防止策略可以配置。
查询数据
分两个阶段,一个分散阶段(scatter phase)和合并阶段(gather phase);分散阶段将query分发到包含相关文档的多个分片中执行查询,合并阶段从众多分片中收集返回结果,然后进行合并、排序、后续操作
查询过程:
使用java 与es通信,客户端:
node client 节点客户端,集群的一部分,不做存储使用,但是知道数据的具体位置,使用9300端口进行通讯
transport client 传输客户端 不加入集群,扮演给集群发送请求的传播介质角色,使用9300端口进行通讯。
基于HTTP协议的,以JSON为数据交互格式的RESTful API:其他所有程序语言都可以使用RESTful API,通过9200端口的与Elasticsearch进行通信
向Elasticsearch发出的请求的组成部分与其它普通的HTTP请求是一样的:
curl -X ':///?<query_string>' -d ''
VERB HTTP方法: GET , POST , PUT , HEAD , DELETE PROTOCOL
http或者https协议(只有在Elasticsearch前面有https代理的时候可用)
HOST Elasticsearch集群中的任何一个节点的主机名,如果是在本地的节点,那么就叫localhost PORT Elasticsearch HTTP服务所在的端口,默认为9200
QUERY_STRING 一些可选的查询请求参数,例如 ?pretty 参数将使请求返回更加美观易读的JSON数据
BODY 一个JSON格式的请求主体(如果请求需要的话)
例如:
curl -XGET 'http://localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } }
Elasticsearch返回一个类似 200 OK 的HTTP状态码和JSON格式的响应主体(除了 HEAD 请求)。上面的请求会得到如下的 JSON格式的响应主体:
{ "count" : 0, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 } }
我们看不到HTTP头是因为我们没有让 curl 显示它们,如果要显示,使用 curl 命令后跟 -i 参数:
curl -i -XGET 'localhost:9200/'
完整请求体:curl -XGET 'localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } }
简写:GET /_count { "query": { "match_all": {} } }
面向文档
应用中的对象很少只是简单的键值列表,更多时候它拥有复杂的数据结构,比如包含日期、地理位置、另一个对象或者数 组
ELasticsearch使用Javascript对象符号(JavaScript Object Notation),也就是JSON
以下使用JSON文档来表示一个用户对象:
{
"email": "john@smith.com",
"first_name": "John",
"last_name": "Smith",
"info": {
"bio": "Eco-warrior and defender of the weak",
"age": 25,
"interests": ["dolphins", "whales"]
},
"join_date": "2014/05/01"
}
开始第一步
建立一个员工目录(索引名字:Megacorp)
假设我们刚好在Megacorp工作,这时人力资源部门出于某种目的需要让我们创建一个员工目录,这个目录用于促进人文关
怀和用于实时协同工作,所以它有以下不同的需求:
数据能够包含多个值的标签、数字和纯文本。
检索任何员工的所有信息。
支持结构化搜索,例如查找30岁以上的员工。
支持简单的全文搜索和更复杂的短语(phrase)搜索
高亮搜索结果中的关键字
能够利用图表管理分析这些数据
索引员工文档
我们首先要做的是存储员工数据,每个文档代表一个员工。在Elasticsearch中存储数据的行为就叫做索引(indexing),不过
在索引之前,我们需要明确数据应该存储在哪里。
在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统
关系型数据库:
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields
Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多
个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。
所以为了创建员工目录,我们将进行如下操作:
为每个员工的文档(document)建立索引,每个文档包含了相应员工的所有信息。
每个文档的类型为 employee 。
employee 类型归属于索引 megacorp 。
megacorp 索引存储在Elasticsearch集群中。
实际上这些都是很容易的(尽管看起来有许多步骤)。我们能通过一个命令执行完成的操作:
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
path: /megacorp/employee/1 包含三部分信息:
名字 说明
megacorp 索引名
employee 类型名
1 这个员工的ID
请求实体(JSON文档),包含了这个员工的所有信息。他的名字叫“John Smith”,25岁,喜欢攀岩。
检索文档
第一个需求是能够检索单个员工的信息。
只要执行HTTP GET请求并指出文档的“地址”——索引、类型和ID既可。
GET /megacorp/employee/1
响应的内容中包含一些文档的元信息,John Smith的原始JSON文档包含在 _source 字段中
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
}
* 我们通过HTTP方法 GET 来检索文档,同样的,我们可以使用 DELETE 方法删除文档,使用 HEAD 方法检查某文档是否存 在。如果想更新已存在的文档,我们只需再 PUT 一次。
搜索姓氏中包含“Smith”的员工
GET /megacorp/employee/_search?q=last_name:Smith
使用QueryDSL查询:
GET /megacorp/employee/_search { "query" : { "match" : { "last_name" : "Smith" } } }
姓氏为“Smith”的员工,但是我们只想得到年龄大于30岁的员工
我们的语句将 做一些改变用来添加过滤器(filter),它允许我们有效的执行一个结构化搜索:
<1>range过滤器,它用于查询所有年龄大于30岁的 --gt代表greater than
<2>这个部分使用match匹配语句进行查询,姓氏为smith的语句。
相关平分
一般Elasticsearch根据相关评分排序,相关评分是根据文档与语句的匹配度来得出,第一个最高分很明确:John Smith 的 about 字段明确的写到“rock climbing”。
但是为什么Jane Smith也会出现在结果里?原因是“rock”在她的 abuot 字段中提及了。因为只有“rock”被提及 而“climbing”没有,所以她的 _score 要低于John。
这个例子很好的解释了es如何进行全文字段搜索且首先返回相关性性最大的结果。相关性(relevance)概念在 es中非常重要,
而这也是它与传统关系型数据库中记录只有匹配和不匹配概念最大的不同。
短语搜索
查询 about 包 含完整短语“rock climbing”的员工
GET /megacorp/employee/_search { "query" : { "match_phrase" : { "about" : "rock climbing" } } }
准确匹配
高亮展示
运行这个语句,与之前相同相同的结果,但是会得到一个新的叫做 highlight 的部分,这里包括了 about 字段中匹 配的文本片段,并且用 <em>包围匹配到的单词。
分析
允许管理者在职员目录中分析
Elasticsearch把这项功能叫做聚合(aggregations),它 允许你在数据基础上生成复杂的统计。它很像SQL中的 GROUP BY 但是功能更强大。
需求:找到最受职员欢迎的兴趣
GET /megacorp/employee/_search { "aggs": { "all_interests": { "terms": { "field": "interests" } } } }
我们可以看到两个职员对音乐有兴趣,一个喜欢森林,一个喜欢运动。
这些聚合的数据并没有被预先计算好,它们从匹配查 询语句的文档中动态生成。
姓"Smith"的人什么兴趣最受欢迎,我们只需要增加合数的语句:
GET /megacorp/employee/_search { "query": { "match": { "last_name": "smith" } }, "aggs": { "all_interests": { "terms": { "field": "interests" } } } }
all_interests 已经变成只包含匹配语句的文档了
聚合也允许分级汇总。例如,让我们统计每种兴趣下职员的平均年龄:
GET /megacorp/employee/_search { "aggs" : { "all_interests" : { "terms" : { "field" : "interests" }, "aggs" : { "avg_age" : { "avg" : { "field" : "age" } } } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2017-02-07 spring事物问题,及解决过程。