Elasticsearch使用手册
介绍
Elasticsearch 是一个由Java编写、基于全文搜索引擎库 Apache Lucene™ 的开源搜索引擎,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,提供一套简单一致的 RESTful API。特性:
- 一个分布式的实时文档存储,每个字段 可以被索引与搜索
- 一个分布式实时分析搜索引擎
- 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
面向文档:
在 Elasticsearch 中,你 对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。
使用
索引:
存储数据到 Elasticsearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存储在哪里。一个 Elasticsearch 集群可以 包含多个 索引 ,相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性 。
路径:路径 /megacorp/employee/1 包含了三部分的信息:
Megacorp:索引名称,employee:类型名称,1:特定雇员的ID
增删改查
1)增:PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
2)删: DELETE
3)改/更新:只需再次 PUT
4)查询是否存在: HEAD
指令来
5)搜索:
请求体查询:参数在请求体中
参考https://www.elastic.co/guide/cn/elasticsearch/guide/current/full-body-search.html
“轻量查询”:参数在查询的url中
参考:https://www.elastic.co/guide/cn/elasticsearch/guide/current/search-lite.html
表达式搜索
索引文档基本用法
索引单个文档:
curl -X GET "localhost:9200/megacorp/employee/1"
一个 HTTP GET
请求并指定文档的地址——索引库、类型和ID。 使用这三个信息可以返回原始的 JSON 文档
返回:
返回结果包含了文档的一些元数据,以及 _source 属性,内容是 John Smith 雇员的原始 JSON 文档:
{
"_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" ]
}
}
检索搜索列表
curl -X GET "localhost:9200/megacorp/employee/_search"
结果返回:
Took:耗时
Timed_out:是否超时
_shards:多少个分片被搜索,_shards:描述了查询分片的信息,查询了多少个分片、成功的分片数量、失败的分片数量等
Hits:搜索结果,hits:搜索的结果,total是全部的满足的文档数目,hits是返回的实际数目(默认是10)
Hits.total – 匹配的文档总数
Hits.hits – 真正的搜索结果数据
_score是文档的分数信息,
{
"took": 6,//
"timed_out": false,
"_shards": { ... },
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "megacorp",
"_type": "employee",
"_id": "3",
"_score": 1,
"_source": {
"first_name": "Douglas",
"last_name": "Fir",
"age": 35,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
},….}
返回结果包括了所有三个文档,放在数组 hits
中。一个搜索默认返回十条结果。
表达式搜索
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
可在表达式搜索中添加filter\boolean等条件组成负责搜索
全文搜索
全文搜索 字段文本匹配, 仅匹配同时包含 “rock” 和 “climbing”
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
返回存在相关度得分:
{
...
"_score": 0.016878016,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [ "music" ]
}
短语搜索
精确匹配,同时含有rock和climbing
"match_phrase" : { "about" : "rock climbing"}
仅匹配同时包含 “rock” 和 “climbing” ,
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
高亮搜索
查询后添加highlight字段,标识该文档符合查询条件
"highlight": {
"fields" : {
"about" : {}
}
索引类型
1.空搜索 GET /_search
2.多索引,多类型
/gb,us/user,tweet/_search
在 gb 和 us 索引中搜索 user 和 tweet 类型
/_all/user,tweet/_search
在所有的索引中搜索 user 和 tweet 类型
3.分页 GET /_search?size=5&from=10
Size:显示应该返回的结果数量,默认是 10
From:显示应该跳过的初始结果数量,默认是 0
注意:先集中排序(分片的结果)后分页
4.轻量搜索要求在查询字符串中传递所有的 参数
(通过一个URL参数来传递查询信息给搜索接口)
GET /megacorp/employee/_search?q=last_name:Smith
详情见:https://www.elastic.co/guide/cn/elasticsearch/guide/current/search-lite.html
复杂搜索
结构化搜索
结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程。比如日期、时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作。比较常见的操作包括比较数字或时间的范围,或判定两个值的大小。
精确查询
当进行精确值查找时,使用过滤器(filters),它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。
- term查询
:
可以用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"price" : 20
}
}
}
}
}
constant_score模式查询以非评分模式
内部过滤器:
在内部,Elasticsearch 会在运行非评分查询的时执行多个操作:
- 查找匹配文档.
term
查询在倒排索引中查找 XHDK-A-1293-#fJ3
然后获取包含该 term 的所有文档。本例中,只有文档 1 满足我们要求。
- 创建 bitset.
过滤器会创建一个 bitset (一个包含 0 和 1 的数组),它描述了哪个文档会包含该 term 。匹配文档的标志位是 1 。本例中,bitset 的值为 [1,0,0,0]
。在内部,它表示成一个 "roaring bitmap",可以同时对稀疏或密集的集合进行高效编码。
- 迭代 bitset(s)
一旦为每个查询生成了 bitsets ,Elasticsearch 就会循环迭代 bitsets 从而找到满足所有过滤条件的匹配文档的集合。执行顺序是启发式的,但一般来说先迭代稀疏的 bitset (因为它可以排除掉大量的文档)。
- 增量使用计数.
Elasticsearch 能够缓存非评分查询从而获取更快的访问,但是它也会不太聪明地缓存一些使用极少的东西。非评分计算因为倒排索引已经足够快了,所以我们只想缓存那些我们 知道 在将来会被再次使用的查询,以避免资源的浪费。
为了实现以上设想,Elasticsearch 会为每个索引跟踪保留查询使用的历史状态。如果查询在最近的 256 次查询中会被用到,那么它就会被缓存到内存中。当 bitset 被缓存后,缓存会在那些低于 10,000 个文档(或少于 3% 的总索引数)的段(segment)中被忽略。这些小的段即将会消失,所以为它们分配缓存是一种浪费。
组合过滤器
SELECT product
FROM products
WHERE (price = 20 OR productID = "XHDK-A-1293-#fJ3")
AND (price != 30)
布尔过滤器:一个 bool
过滤器由三部分组成:
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}
Must
:所有的语句都 必须(must) 匹配,与 AND
等价。
must_not
:所有的语句都 不能(must not) 匹配,与 NOT
等价。
Should
:至少有一个语句要匹配,与 OR
等价。
Bool可以嵌套多个bool过滤器
参考:https://www.elastic.co/guide/cn/elasticsearch/guide/current/combining-filters.html
查找多个精确值:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_finding_multiple_exact_values.html
范围range
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_ranges.html
处理空值
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_dealing_with_null_values.html
处理缓存:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/filter-caching.html
全文搜索
https://www.elastic.co/guide/cn/elasticsearch/guide/current/full-text-search.html
多字段搜索
https://www.elastic.co/guide/cn/elasticsearch/guide/current/multi-field-search.html
近似匹配
https://www.elastic.co/guide/cn/elasticsearch/guide/current/multi-field-search.html
部分匹配
https://www.elastic.co/guide/cn/elasticsearch/guide/current/multi-field-search.html
控制相关度
https://www.elastic.co/guide/cn/elasticsearch/guide/current/controlling-relevance.html
聚合:
需要明白两个主要的概念:
桶(Buckets)
满足特定条件的文档的集合,类似于Group by,桶也可以被嵌套在其他桶里面,提供层次化的或者有条件的划分方案
指标(Metrics)
对桶内的文档进行统计计算,类似于count\max\sum等
SELECT COUNT(color) FROM table GROUP BY color
COUNT(color) 相当于指标。 |
|
GROUP BY color 相当于桶。 |
简单聚合:哪个颜色的汽车销量最好
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
}
}
}
}
聚合操作被置于顶层参数 aggs / aggregations 。 |
|||||||||
然后,可以为聚合指定一个我们想要名称,本例中是: popular_colors 。 |
|||||||||
最后,定义单个桶的类型 terms 。
结果: { ... "hits": { "hits": [] }, "aggregations": { "popular_colors": { "buckets": [ { "key": "red", "doc_count": 4 }, { "key": "blue", "doc_count": 2 }, { "key": "green", "doc_count": 2 } ] } } }
查询条件+聚合:度量+聚合: https://www.elastic.co/guide/cn/elasticsearch/guide/current/_adding_a_metric_to_the_mix.html
2)简单聚合:哪个颜色的汽车销量最好 GET /cars/transactions/_search { "size" : 0, "query" : { "match_all" : {} }, "aggs" : { "colors" : { "terms" : { "field" : "color" } } } } |
例子3:度量
过滤+聚合:
因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。
到聚合—》条形图
明日: 地理位置
原理
ElasticSearch 的主旨是随时可用和按需扩容。 而扩容可以通过购买性能更强大( 垂直扩容 ,或 纵向扩容) 或者数量更多的服务器( 水平扩容 ,或 横向扩容 )来实现。El倾向于横向扩容,为集群添加更多的节点。
Elasticsearch 尽可能地屏蔽了分布式系统的复杂性。这里列举了一些在后台自动执行的操作:
- 分配文档到不同的容器 或 分片 中,文档可以储存在一个或多个节点中
- 按集群节点来均衡分配这些分片,从而对索引和搜索过程进行负载均衡
- 复制每个分片以支持数据冗余,从而防止硬件故障导致的数据丢失
- 将集群中任一节点的请求路由到存有相关数据的节点
- 集群扩容时无缝整合新节点,重新分配分片以便从离群节点恢复
一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
当一个节点被选举成为 主 节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以它同时也成为了主节点。
作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。
- 集群健康:
GET /_cluster/health
status 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
green所有的主分片和副本分片都正常运行。
yellow所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red有主分片没能正常运行。
- 索引:
索引 —— 保存相关数据的地方。 索引实际上是指向一个或者多个物理 分片 的 逻辑命名空间 。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}