赞
踩
全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选。它可以快速地储存、搜索和分析海量数据。维基百科、StackOverflow、Github 都采用它 Elastic 的底层是开源库 Lucene。但你没法直接用 Lucene,必须自己写代码去调用它的接口。Elastic 是 Lucene 的封装,提供了 REST API 的操作接口,开箱即用。
动词,相当于 MySQL 中的 insert
名词,相当于 MySQL 中的 Database
在 Index(索引)中,可以定义一个或多个类型
类似于 MySQL 中的 Table,每一种类型的数据放在一起
保存在某个索引(Index)下,某种类型(Type)的一个数据(Document),文档是 JSON 格式的,Document 就像是 MySQL 中的某个 Table 里面的内容。
在 Elasticsearch 中存储数据的行为就叫做索引(indexing),不过在索引之前,我们需要明确数据应该存储在哪里。
在 Elasticsearch 中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以简单的对比传统关系型数据库:
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields
Elasticsearch 集群可以包含多个索引,每一个索引可以包含多个类型,每一个类型包含多个文档,然后每个文档包含多个字段。
索引含义的区分
你可能已经注意到索引(index)这个词在Elasticsearch中有着不同的含义,所以有必要在此做一下区分:
索引(名词) 如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是indices 或indexes。
索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的 INSERT 关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。
传统数据库为特定列增加一个索引,例如 B-Tree 索引来加速检索。
Elasticsearch 和 Lucene 使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。
如上图所示:我们将 1-红海行动(文档)索引到某个类型,Elasticsearch 会将这个文档进行分词,将红海行动拆分为红海和行动,如上表第一条记录:红海这个分词存在于 1 号记录,同理行动存在于 1 号记录里,以此类推,Elasticsearch 将上述五条记录维护在上述表中,这就是倒排索引表。
当我们要检索红海特工行动的时候,Elasticsearch 也会将检索的文档进行分词为:红海,特工,行动。红海 1-5 号记录都有,特工存在五号记录,行动存在于 1-3 号记录。3 号记录三个分词命中了两个,5 号记录 4 单词命中了两个,所以红海特工行动这条文档,3 号记录相关性得分较高,检索 3 号记录排在前面。
//查看所有节点
GET /_cat/nodes
//看 es 健康状况
GET /_cat/health
//查看主节点
GET /_cat/master
//查看所有索引,相当于 mysql 的 show databases;
GET /_cat/indices
2.2.1 保存一个数据,保存在哪个索引的哪个类型下(翻译成 MySQL 的话就是在某个数据库某张表中保存一条记录),指定用哪个唯一标识。
//在customer索引下的external类型下保存1号数据。
PUT customer/external/1
{
"name": "John Doe"
}
点击 send,返回如上数据:_符号开头的叫元数据,“_index”: “customer” 表面该文档存在 customer 索引中,“_type”: “external”,表面该文档存在 external 类型下,“_id”: “1”,唯一标识,“_version”: 1,版本信息,“result”: “created”,第一次请求表示新建状态。
2.2.2 同样请求再次点击 send,变成更新操作。
2.2.3 PUT 不带 id 报错
2.2.4 POST 发送请求
PUT和POST都可以,
POST新增,如果不指定id,会自动生成id。指定id就会修改这个数据,并新增版本号。
PUT可以新增可以修改,PUT必须指定id,由于PUT需要指定id,我们一般都用来做修改操作,不指定id会报错。
//查询 id 为 1 的文档信息
GET customer/external/1
{
"_index": "customer",//在哪个索引
"_type": "external",//在哪个类型
"_id": "1",//记录 id
"_version": 2,//版本号
"_seq_no": 1, //并发控制字段,每次更新就会+1,用来做乐观锁
"_primary_term": 1,//同上,主分片重新分配,如重启,就会变化
"found": true,
"_source": { //真正的内容
"name": "John Doe"
}
}
发送两个请求,A请求:如果 _seq_no = 1 且 if_primary_term = 1,那么将 name 改为 1,如下图所示
B 请求:如果 _seq_no = 1 且 if_primary_term = 1,那么将 name 改为 2,如下图所示
由于 A 先发送请求修改 name 为 1 所以_seq_no 已经不再是为 1 了,B再发送修改请求时就出现如上错误。而 B 要再次修改的话得让 _seq_no=3&if_primary_term=7。
POST customer/external/1/_update
{
"doc":{
"name": "John Doew"
}
}
POST customer/external/1
{
"name": "John Doe2"
}
PUT customer/external/1
{
"name": "John Doe"
}
三种更新的不同:
POST操作会对比源文档数据,如果相同不会有什么操作,文档version不增加
PUT 操作总会将数据重新保存并增加version版本;
带_update 对比元数据如果一样就不进行任何操作。
看场景;对于大并发更新,不带update;对于大并发查询偶尔更新,带update;对比更新,重新计算分配规则。
//更新同时增加属性
POST customer/external/1/_update
{
"doc":{
"name": "John Doew",
"age": 20
}
}
#PUT 和 POST 不带_update 也可以
DELETE customer/external/1
DELETE customer
POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
使用 Kibana 工具批量插入数据
#语法格式:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
bulk API 以此按顺序执行所有的 action(动作)。如果一个单个的动作因任何原因而失败,它将继续处理它后面剩余的动作。当 bulk API 返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是不是失败了。
我准备了一份顾客银行账户信息的虚构的 JSON 文档样本。每个文档都有下列的 schema(模式):
{
"account_number": 0,
"balance": 16623,
"firstname": "Bradshaw",
"lastname": "Mckenzie",
"age": 29,
"gender": "F",
"address": "244 Columbus Place",
"employer": "Euron",
"email": "bradshawmckenzie@euron.com",
"city": "Hobucken",
"state": "CO"
}
导入测试数据 POST bank/account/_bulk 测试数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。