Elasticsearch笔记1

学习整理自官方文档

ES与数据库的对应关系

  • 名词
ES MYSQL
index(索引) database(数据库)
type(类型 已废弃) table(表)
document(文档) row(行)
field(字段) line(列)

type已于6.0.0之后版本废弃,一个索引只能有一个类型

  • 遍历方式

ES有分片的概念,一个大的索引会被分成多个分片来进行存储数据,使用分布式的架构对分片进行并行搜索(基于倒排)

传统数据库的遍历,属于正向全表扫描

  • 索引

ES采用倒排索引,通过把文档字段分词,生成一个term index, term dictionary, posting list建立倒排索引

mysql通过B+树建立正排索引,通过索引正向查询

  • 事务

ES没有事务,数据修改,删除不能回滚

mysql支持事务

  • 数据量

在面对大数据量简单计算的时候es的效率原高于mysql等传统数据库,但是在定位某一个唯一值(如用会员id找会员)时并不需要es
但在大数据的相似计算与查找或简单计算时,es的分布式并行计算有绝对的优势

  • 协议

ES支持http
mysql支持jdbc

环境配置

win10
Elasticsearch 7.0.0
启动后进入 http://localhost:9200进行测试
在这里插入图片描述
Kibana 7.0.0
启动后进入http://localhost:5601进行测试
在这里插入图片描述

查看Elasticsearch信息

GET /
在这里插入图片描述

创建索引及文档

PUT 索引/类型/文档id
{
  "字段1": "date",
  "字段2": date,
}
  • RDMS中,通常需要有专用的语句来生产相应的数据库,表格,然后才可以输入相应的记录。但是对于ES,会自动生成对应的index及type。自从Elasticsearch 6.0以后,一个index只能有一个type。如果创建另外一个type的话,系统会告诉我们是错误的。执行结果中有一个版本信息,如果这个指定id的document之前没有被创建过的话,它会显示为1。之后如果更改这个document,它的版本会每次自动增加1。
    在这里插入图片描述
    每次执行POST或者PUT接口时,如果文档已经存在,那么相应的版本就会自动加1,之前的版本抛弃。如果不想直接覆盖的话,可以使用_create端点接口来实现,如果文档已经存在的话,会收到一个错误的信息.
    在这里插入图片描述

  • 在上面当写入数据时,有意识地把文档的id在命令中写了出来。如果不写这个id的话,ES会自动生产一个id:

在这里插入图片描述
看到右边的一个id像是一个随机的数值,同时可以看到它的版本信息为1。
也可以看出来系统所给出来的字段都是以下划线的形式给出来的,比如:_id, _shards, _index, _typed等。

  • 通常对一个通过上面方法写入到Elasticsearch的文档,在默认的情况下并不马上可以进行搜索。这是因为在Elasticsearch的设计中,有一个叫做refresh的操作。它可以使更改可见以进行搜索的操作。通常会有一个refresh timer来定时完成这个操作。这个周期为1秒。这也是通常所说的Elasticsearch可以实现秒级的搜索。当然这个timer的周期也可以在索引的设置中进行配置。如果我们想让结果马上可以对搜索可见,可以用如下的方法:
POST twitter/_doc/1?refresh=true
{
  "user": "GB",
  "uid": 1,
  "city": "Beijing",
  "province": "Beijing",
  "country": "China"
}
  • 上面的方式可以强制使Elasticsearch进行refresh的操作,当然这个是有代价的。频繁的进行这种操作,会使Elasticsearch变得非常慢。另外一种方式是通过设置refresh=wait_for。这样相当于一个同步的操作,它等待下一个refresh周期发生完后,才返回。这样可以确保在调用上面的接口后,马上可以搜索到刚才录入的文档:
POST twitter/_doc/1?refresh=wait_for
{
  "user": "GB",
  "uid": 1,
  "city": "Beijing",
  "province": "Beijing",
  "country": "China"
}

查看文档

GET 索引/类型/文档id
在这里插入图片描述
如果只对source的内容感兴趣的话,可以使用
GET 索引/类型/文档id/_source
可以直接得到source的信息:在这里插入图片描述
也可以只获取source的部分字段:
GET 索引/类型/文档id?_source=字段1,字段2...
在这里插入图片描述
如果想一次请求查找多个文档,可以使用_mget接口

在这里插入图片描述
也可以只获得部分字段:
在这里插入图片描述
同时请求id为1和2的两个文档,也可以简单地写为:

GET twitter/_doc/_mget
{
  "ids": ["1", "2"]
}

它和上面的做一个是一样的。使用一个命令同时获取id为1及2的文档。

修改文档

  • 在上面看到了可以使用POST的命令来修改改一个文档。通常使用POST来创建一个新的文档。在使用POST的时候,甚至不用去指定特定的id,系统会帮我们自动生成。但是修改一个文档时,通常会使用PUT来进行操作,并且,需要指定一个特定的id来进行修改:

在这里插入图片描述

  • 使用PUT的这个方法,每次修改一个文档时,需要把文档的每一项都要写出来。这对于有些情况来说并不方便。可以使用POST _update来进行修改:
    在这里插入图片描述
  • 在关系数据库中,通常是对数据库进行搜索,然后才进行修改。在这种情况下,事先通常并不知道文档的id,需要通过查询的方式来进行查询,然后进行修改。ES也提供了相应的REST接口。

在这里插入图片描述
在这里插入图片描述
对于那些名字是中文字段的文档来说,在painless语言中直接打入中文字段名字并不能被认可。可以使用如下的方式来操作:

POST edd/_update_by_query
{
  "query": {
    "match": {
      "姓名": "张彬"
    }
  },
  "script": {
    "source": "ctx._source[\"签到状态\"] = params[\"签到状态\"]",
    "lang": "painless",
    "params" : {
      "签到状态":"已签到"
    }
  }
}

也可以通过update接口,使用script的方法来进行修改。这个方法也是需要知道文档的id:
在这里插入图片描述

更新文档

术语“upsert”宽松地表示更新或插入,即更新文档(如果存在),否则,插入新文档。

仅在文档事先存在的情况下,在前面的代码中看到的部分更新才有效。 如果具有给定ID的文档不存在,Elasticsearch将返回一个错误,指出该文档丢失。
在这里插入图片描述
doc_as_upsert参数检查具有给定ID的文档是否已经存在,并将提供的doc与现有文档合并。 如果不存在具有给定ID的文档,则会插入具有给定文档内容的新文档。

下面的示例使用doc_as_upsert合并到ID为3的文档中,或者如果不存在则插入一个新文档:
在这里插入图片描述
在这里插入图片描述

检查文档是否存在

  • 有时候想知道一个文档是否存在,可以使用如下的方法:
    HEAD 索引/类型/文档id
    在这里插入图片描述
    在这里插入图片描述

删除文档

  • 如果想删除一个文档的话,可以使用如下的命令:
    DELETE 索引/类型/文档id
    在这里插入图片描述
    在这里插入图片描述
  • 在关系数据库中,通常是对数据库进行搜索,然后才进行删除。在这种情况下,事先通常并不知道文档的id。需要通过查询的方式来进行查询,让后进行删除。ES也提供了相应的REST接口。
POST twitter/_delete_by_query
{
  "query": {
    "match": {
      "city": "上海"
    }
  }
}

这样我们就把所有的city是上海的文档都删除了。

删除索引

除一个index是非常直接的。可以直接使用如下的命令来进行删除:
DELETE 索引
在这里插入图片描述

批处理命令

了解了如何使用REST接口来创建一个index,并为之创建,读取,修改,删除文档(CRUD)。因为每一次操作都是一个REST请求,对于大量的数据进行操作的话,这个显得比较慢。ES创建一个批量处理的命令供使用。这样在一次REST请求中,就可以完成很多的操作。

使用如下的命令来进行bulk操作:

POST _bulk
{ "index" : { "_index" : "twitter", "_id": 1} }
{"user":"双榆树-张三","message":"今儿天气不错啊,出去转转去","uid":2,"age":20,"city":"北京","province":"北京","country":"中国","address":"中国北京市海淀区","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"东城区-老刘","message":"出发,下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区台基厂三条3号","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"东城区-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝阳区-老贾","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区建国门","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝阳区-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区国贸","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹桥-老吴","message":"好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中国","address":"中国上海市闵行区","location":{"lat":"31.175927","lon":"121.383328"}}

在这里插入图片描述
在上面的命令中,使用了bulk指令来完成我们的操作。在输入命令时,们需要特别的注意:不要添加除了换行以外的空格,否则会导致错误。为了说明问题的方便,在每一个文档里,特别指定了每个文档的id。
bulk指令是高效的,因为一个请求就可以处理很多个操作。在实际的使用中,必须注意的是:一个好的起点是批量处理1000到5,000个文档,总有效负载在5MB到15MB之间。如果payload过大,那么可能会造成请求的失败。如果你想更进一步探讨的话,可以使用文件accounts.json来做实验。

  • 上面已经使用了index来创建6条文档记录。也可以尝试其它的命令,比如create:
POST _bulk
{ "create" : { "_index" : "twitter", "_id": 1} }
{"user":"双榆树-张三","message":"今儿天气不错啊,出去转转去","uid":2,"age":20,"city":"北京","province":"北京","country":"中国","address":"中国北京市海淀区","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"东城区-老刘","message":"出发,下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区台基厂三条3号","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"东城区-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝阳区-老贾","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区建国门","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝阳区-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区国贸","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹桥-老吴","message":"好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中国","address":"中国上海市闵行区","location":{"lat":"31.175927","lon":"121.383328"}}

在上面使用了create来创建第一个id为1的记录。因为之前已经创建过了,所以可以看到如下的信息:
在这里插入图片描述
从上面的信息,可以看出来index和create的区别。index总是可以成功,它可以覆盖之前的已经创建的文档,但是create则不行,如果已经有以那个id为名义的文档,就不会成功。

  • 批量删除命令
POST _bulk
{ "delete" : { "_index" : "索引", "_id": id1 }}
{ "delete" : { "_index" : "索引", "_id": id2 }}
  • 批量更新命令
POST _bulk
{ "update" : { "_index" : "索引", "_id": id1 }}
{"doc": { "字段": "new date"}}
{ "update" : { "_index" : "索引", "_id": id2 }}
{"doc": { "字段1": "new datr","字段2":"new date"}}

注意:通过bulk API为数据编制索引时,不应在集群上进行任何查询/搜索。 这样做可能会导致严重的性能问题。

查询索引

  • 如果想查询到所有的输入的文档,可以使用如下的命令来进行查询:
    POST 索引/_search
    在这里插入图片描述
    上面的结果显示,已经有6条文档记录产生了。
  • 可以通过使用_count命令来查询有多少条数据:
    GET 索引/_count
    在这里插入图片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章