目录html
发表日期:2019年9月19日web
在学习新的内容以前,先回顾一下上节的内容,上节主要讲述了如下的内容:sql
这节将涉及index、type、document的增删查改相关的内容。
index就像sql中的库,type就像sql中的表,document就像sql中的记录。
这节认识index,type,document,会帮助咱们认识ElasticSearch数据存储的逻辑结构。就好像你学SQL要先学会了建库、建表,才能插入记录。而一些更深一点的内容,例如如何对document进行搜索、排序,这些将留到下一节再讲。数据库
索引index是存储document文档数据的结构,意义相似于关系型数据库中的数据库。express
在上一节的hello world中,咱们并无讲如何建立索引,那里直接就插入了数据,那样的话ElasticSearch会帮咱们以默认的配置来自动建立索引。
下面讲一下如何手动建立索引:json
语法:数组
// 语法: PUT /索引名 { index的配置(primary shard的数量等) }
例子:数据结构
// 例子(不带配置信息的话以默认配置建立)【请不要复制这个注释!】: PUT /product // 例子(带配置信息的话以配置信息建立)【请不要复制这个注释!】 PUT /product { "settings":{ "index":{ "number_of_shards":3, "number_of_replicas":1 } } }
在上述的例子中:number_of_shards是主分片的数量;number_of_replicas是副本分片的数量(这里提一下,number_of_replicas副本分片的数量是面向主分片的,因此这个值为1时表明每个主分片有一个副本分片)。架构
返回结果:app
{ "acknowledged": true, "shards_acknowledged": true, "index": "product" }
【在插入一个文档的时候,若是index尚未建立,那么会自动建立,这时候index的一些配置会采用默认的配置,默认的主分片数量是5,副本分片数量是1】
语法:GET /索引名
效果:返回指定索引的信息
例子:GET /product
返回结果解析:
命令:GET /_cat/indices?v
效果:查看全部索引,显示索引的健康状态等信息。
【若是没有v选项,那么就不会有第一行关于该列意义的头部】
返回结果解析:
语法:DELETE /索引名
【支持同时删除多个索引,以逗号分割,如DELETE /testindex1,testindex2】
语法例子:DELETE /product
返回结果:【当acknowledged为true的时候表明删除成功】
{ "acknowledged": true }
【修改索引主要是修改分片数量、mapping、分词器,因为mapping和分词器涉及很深,须要前置知识,因此留到后面讲。】
不讲语法了,直接看例子:
PUT /product/_settings { "index":{ "number_of_replicas":2 } }
关闭索引是为了避免修改索引的配置时他人进行文档读写。关闭索引后,就只能获取索引的配置信息,而不能读写索引中的document。有时候也用于关闭一些无用的索引来减小资源消耗。
语法:
POST /索引名/_close
POST /索引名/_open
索引别名是一个“别名”,但可以像索引名那样使用,它的使用场景一方面是“使用更简洁的索引名来获取数据”,另外一个方面是“经过索引别名来指向索引(别名B指向索引A),方便修改指向的索引,用于解决可能的更换索引的场景(好比你须要统一修改原有索引的信息,那你能够新建索引C,C存储了修改后的数据,更改指向本来索引A的索引别名B指向C)。”
语法:
POST /_aliases { "actions":[ { "add":{ "index":"索引名", "alias":"索引别名" } } ] }
例子:
POST /_aliases { "actions":[ { "add":{ "index":"product", "alias":"pdt" } } ] }
GET /product
GET /product/_alias
GET /product
的时候直接用上别名】语法:
POST /_aliases { "actions":[ { "remove":{ "index":"索引名", "alias":"索引别名" } } ] }
例子:
POST /_aliases { "actions":[ { "remove":{ "index":"product", "alias":"pdt" } } ] }
【你应该看到了,actions里面是一个数组,因此你是能够同时进行多个操做的。】
本小节讲了如何建立索引,如何查看索引、如何删除索引、如何修改索引(修改副本分片数量)、如何关闭/开启索引、如何定义索引别名。
目的在于介绍如何建立存储document的逻辑结构--索引,虽然咱们有时候是不须要手动显示建立索引的,但手动建立是个必须了解的知识,由于mapping和分词器有时候须要手动来指定。
类型type也是用于存储document的逻辑结构,相对于index来讲,type是index的下级,因此一般在面向有实际意义的数据时,index做为大类的划分,type做为小类的划分。好比若是把book书做为一个大类来创建index的话,那么书的类型(小说类、文学类、IT技术类等)就能够做为type。
你可能觉得下面要讲如何CRUD类型type了吧。但其实这里并不须要讲这些,由于type其实并不真的用来划分逻辑结构,它只是意义上的!ElasticSearch使用了Lucene的底层架构,而Lucene是没有type。
上面说了,index就像sql中的库,type就像sql中的表,document就像sql中的记录。
但事实上,ElasticSearch“真正用于分隔数据的结构“只有index,而没有type,type实际上做为了一个元数据(相似SQL中的id,做为额外的标识数据)来实现逻辑划分。【若是你不懂的话,能够从SQL方面想,就好像一个职员表,一条记录中的某一个字段说明了他属于哪一个部门】。固然了,这是一些偏原理的内容了。这些都将留到原理篇来阐述。这里仅仅是浅尝即止。
不过因为没有type没有真实地用于分隔数据,因此要注意结构类型误差太大的数据仍是不要放在一个index好。
以前说了,index用来划分大类,type用来划分小类。而可能有些人会把这个大类定的过大,好比电影和书籍这两个小类(type)的数据大可能是不同的,但他们均可以属于娱乐这一个大类(index),因为type并无真实地用于分隔数据地用于存储数据,因此数据存储的时候针对的仍是index。
ElaticSearch并非彻底无结构的,不要与某些NoSQL数据库混为一谈,虽然它的结构很是灵活(面向json,能够随意增长字段)。在index中还有一个mapping,mapping管理了整个index的各个字段的属性,也就是定义了整个index中document的结构。咱们在index下不一样type中定义的document的字段都会在mapping中。因此说,若是你定义的多个type的结构误差太大,那么会致使mapping须要存储的字段的数据过多,同时也影响index的物理存储结构,由于index会按照mapping来存储数据。【换到SQL中的话,也就是好比你有一个商品表,商品表下面有各类商品(书籍、食物),而它们的数据是很不同的,好比书籍有出版日期,食物有保质期,若是把它们都放到一个表中的话,那么就会致使这个表的字段过多。】
如何测试document文档的数据结构是面向index?【这个测试你能够不作,如今仅仅记住上面的知识点,测试后面再作,由于这个涉及到一些后面的知识】
1.定义一个document的一个字段为date类型;而后在另外一个type中添加为text类型的同名字段。
当咱们直接插入document的时候,若是不指定document的数据结构,那么ElastciSearch会基于dynamic mapping来自动帮咱们声明每个字段的数据类型,好比"content":"hello world!"会被声明成字符串类型,"post_date":"2017-07-07"会被认为是date类型。若是咱们首先在一个type中声明了content为字符串类型,再在另一个type中声明成日期类型,这会报错,由于对于index来讲,这个content已经被声明成字符串类型了。2.查看mapping:
在查看mapping的时候,咱们是经过查看索引来查看的,其实也反向证实了mapping是面向index的。
文档的格式是json式的。
对于文档,有几个主要的标识信息:_index(插入到哪一个索引中),_type(插入到哪一个类型中),_id(文档的id是多少),在插入一个文档的时候,这几个信息也是必须的。
语法:
PUT /index/type/id json格式的数据
例子:
PUT /douban/book/4 { "book_id":4, "book_name":"Other Voices, Other Rooms", "book_author":"Truman Capote", "book_pages":240, "book_express":"Vintage", "publish_date":"1994-02-01", "book_summary":""" Truman Capote’s first novel is a story of almost supernatural intensity and inventiveness, an audacious foray into the mind of a sensitive boy as he seeks out the grown-up enigmas of love and death in the ghostly landscape of the deep South. At the age of twelve, Joel Knox is summoned to meet the father who abandoned him at birth. But when Joel arrives at the decaying mansion in Skully’s Landing, his father is nowhere in sight. What he finds instead is a sullen stepmother who delights in killing birds; an uncle with the face—and heart—of a debauched child; and a fearsome little girl named Idabel who may offer him the closest thing he has ever known to love.""" }
结果解析:
_index
:插入到哪一个index中。_type
:插入到哪一个type中。_id
:插入的文档的id是多少。_version
:版本,对这个ID的文档的操做次数
语法:
GET /index/type/id
例子:
GET /douban/book/1
结果解析:
语法:
// 全替换(覆盖)式更新:会使用新的json数据直接覆盖原有的【请不要复制注释】 PUT /index/type/id json数据 // 部分替换式更新:只会覆盖指定数据 POST /index/type/id/_update { "doc": { "须要修改的字段": "修改值" [,"须要修改的字段": "修改值"] } }
例子:
【全替换语句与插入差很少,因此不举例了】 POST /douban/book/4/_update { "doc": { "book_pages":241, "publish_date":"1994-02-02" } }
结果解析:
返回结果与插入时大概一致,不一样的时result变成了updated
语法:
DELETE /index/type/id
例子:
【删除后能够从新执行插入语句恢复数据】
DELETE /douban/book/4
结果解析:
返回结果与插入时大概一致,不一样的时result变成了deleted.
语法:
GET /index/type/_search GET /index/type/_search { "query":{ "match_all": {} } }
例子:
GET /douban/book/_search GET /douban/book/_search { "query":{ "match_all": {} } }
上面介绍了关于文档的CRUD基操,但还有不少东西没讲,这些将留到后面讲,包括:文档的字段的数据类型、文档的搜索、文档的元数据(_index,_type,_id等)
这节讲了如何对文档进行CRUD操做,PUT用于插入,GET用于查询,PUT和POST用于修改,DELETE用于删除。