Elasticsearch 学习笔记Day 04

148 阅读6分钟

hi,我是蛋挞,一个初出茅庐的后端开发,希望可以和大家共同努力、共同进步!


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

  • 起始标记->Elasticsearch入门(15讲):「11 | 基本概念:文档的基本CRUD与批量操作」
  • 结尾标记->Elasticsearch入门(15讲):「12 | 基本概念:倒排索引介绍」

文档的基本CRUD与批量操作

文档的CRUD

  • Type 名,约定都用__doc
  • Create -如果ID已经存在,会失败
  • Index -如果ID不存在,创建新的文档。否则,先删除现有的文档,再创建新的文档,版本会增加
  • Update- 文档必须已经存在,更新只会对相应字段做增量修改

image.png

Create 一个文档

  • 支持自动生成文档 id 和指定文档id 两种方式
  • 通过调用 “post / users /_doc”
    • 系统会自动生成 document id
  • 使用 HTTP PUT user/_create/1 创建时,URI中显示指定_create,此时如果该id文档已经存在,操作失败

image.png

Get 一个文档

  • 找到文档, 返回HTTP 200
    • 文档元信息
      • _index /_type /
      • 版本信息,同一个Id的文档,即使被删除,Version号也会不断增加
      • source中默认包含了文档的所有原始信息
  • 找不到文档, 返回HTTP 404

image.png

Index 文档

  • Index 和 Create 不一样的地方:如果文档不存在,就索引新的文档。否则现有的文档会被删除,新的文档被索引。版本信息 + 1

image.png

Update 文档

  • Update 方法不会删除原来的文档,而是实现真正的数据更新
  • Post 方法/ Payload 需要包含在"doc"中

image.png

Demo

  • Create Document (auto ID generate)

image.png

  • Get Documnet By Id

image.png

  • Create Document (指定ID)

image.png 再次点击执行 image.png 可以看到操作已经失败,当前文档已经存在,因为Elasticsearch是通过版本号来判断冲突的。

  • Index document

Index 当发现指定文档已经存在时,会优先删除掉旧的文档,再将新文档进行写入,版本号 +1 image.png 再次读取 image.png

  • Update Docunment

在原有的文档上增加字段 image.png 再次读取 image.png

Bulk API

Bulk API 为的是解决每次发送请求时对网络开销过大的影响性能的问题。核心思想是: 能不能在一次rest的请求当中,去执行多次不同的操作。

  • 支持在一次API调用中,对不同的索引进行操作
  • 支持四种类型操作
    • Index
    • Create
    • Update
    • Delete
  • 可以再URI中指定Index,也可以在请求的Payload中进行
  • 操作中单条操作失败,并不会影响其他操作
  • 返回结果包括了每一条操作执行的结果

image.png

Demo:

image.png 执行结果: image.pngimage.png

批量读取 - mget

批量操作,可以减少网络连接所产生的开销,提高性能 image.pngimage.png

demo:

image.png

批量查询 - mserach

demo:

image.png 执行结果: image.pngimage.pngimage.pngimage.pngimage.png

常见错误返回

image.png

CodeDemo

############Create Document############ #create document. 自动生成 _id POST users/_doc { "user" : "Mike", "post_date" : "2019-04-15T14:12:12", "message" : "trying out Kibana" }

#create document. 指定Id。如果id已经存在,报错 PUT users/_doc/1?op_type=create { "user" : "Jack", "post_date" : "2019-05-15T14:12:12", "message" : "trying out Elasticsearch" }

#create document. 指定 ID 如果已经存在,就报错 PUT users/_create/1 { "user" : "Jack", "post_date" : "2019-05-15T14:12:12", "message" : "trying out Elasticsearch" }

###Get Document by ID #Get the document by ID GET users/_doc/1

###Index & Update #Update 指定 ID  (先删除,在写入) GET users/_doc/1

PUT users/_doc/1 { "user" : "Mike" }

#GET users/_doc/1 #在原文档上增加字段 POST users/_update/1/ { "doc":{ "post_date" : "2019-05-15T14:12:12", "message" : "trying out Elasticsearch" } }

###Delete by Id #删除文档 DELETE users/_doc/1

###Bulk 操作 #执行两次,查看每次的结果

#执行第1次 POST _bulk POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test2", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }

#执行第2次 POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test2", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }

###mget 操作 GET /_mget { "docs" : [ { "_index" : "test", "_id" : "1" }, { "_index" : "test", "_id" : "2" } ] }

#URI中指定index GET /test/_mget { "docs" : [ { "_id" : "1" }, { "_id" : "2" } ] }

GET /_mget { "docs" : [ { "_index" : "test", "_id" : "1", "_source" : false }, { "_index" : "test", "_id" : "2", "_source" : ["field3", "field4"] }, { "_index" : "test", "_id" : "3", "_source" : { "include": ["user"], "exclude": ["user.location"] } } ] }

###msearch 操作 POST kibana_sample_data_ecommerce/_msearch {} {"query" : {"match_all" : {}},"size":1} {"index" : "kibana_sample_data_flights"} {"query" : {"match_all" : {}},"size":2}

###清除测试数据 #清除数据 DELETE users DELETE test DELETE test2

相关阅读

倒排索引介绍

正排与倒排索引

用一本书作为一个例子 image.png

目录 - 正排

如果没有目录,理论上我们也是可以正常阅读的。只是当我们合上这本书的时候,下次再翻开来查找,就比较耗费时间了,我们通过给一本书来增加目录页,就可以快速的了解这本书的大致内容分布以及每个章节页面分布的页码数,这样我们在查询内容的时候效率就会非常的高了,所以书的目录就是书本内容的一种简单索引。image.png

eg:快速查找“benchmarking”所在的页面

正排索引和倒排索引

有一些技术的书籍会在书的最后提供一个索引页,只需要查找目标单词,就可以定位关键词在书本出现的位置了,简单来说,将图书和搜索引擎做一个类比,图书当中的目录页就是一个正排索引,在书最后的索引页就是一个倒排索引的一种简单实现。 在搜索引擎中, 正排索引指的是-> 文档ID 到 文档内容 和 单词的关联, 倒排索引指的是-> 单词 到 文档ID 的关系 image.png

倒排索引的核心组成

  • 倒排索引包含两个部分
    • 单词词典(Term Dictionary), 记录所有文档的单词,记录单词到倒排列表的关联关系
      • 单词词典一般比较大,可以通过B +树或哈希拉链法实现,以满足高性能的插入与查询
    • 倒排列表(Posting List)-记录了单词对应的文档结合,由倒排索引项组成
      • 倒排索引项(Posting)
        • 文档 ID
        • 词频 TF -该单词在文档中出现的次数,用于相关性评分
        • 位置 (Position) - 单词在文档中分词的位置。用于语句搜索 (phrase query)
        • 偏移 (Offset) -记录单词的开始结束位置,实现高亮显示

一个例子 - Elasticsearch

image.png

Elasticsearch的倒排索引

  • Elasticsearch 的JSON文档中的每个字段,都有自己的倒排索引
  • 可以指定对某些字段不做索引
    • 优点:节省存储空间
    • 缺点:字段无法被搜索

CodeDemo

POST _analyze { "analyzer": "standard", "text": "Mastering Elasticsearch" }

POST _analyze { "analyzer": "standard", "text": "Elasticsearch Server" }

POST _analyze { "analyzer": "standard", "text": "Elasticsearch Essentials" }

相关阅读

总结


学习了文档的CRUD操作以及Bulk API、MGet API,MSearch API,这些批量的操作可以帮助我提高API调用的性能,需要注意的是,在每次发送API请求的时候不要一次发送过多的数据,因为如果发送过多的数据也会对Elasticsearch集群产生过大的压力,反而会造成性能的下降。学习了倒排索引以及倒排索引的数据结构是什么样子的。

此文章为2月Day4学习笔记,内容来源于极客时间《Elasticsearch 核心技术与实战》