17-Elasticsearch与关系数据库的对比(索引 Indices的理解,主要概念的理解)

时间:2023-01-04 00:03:11

1. 谈谈Elasticsearch 和 传统关系型数据库的 对比?那些是相似的,那些是不同的

ElasticSearch与关系型数据库的相似:

名称 概念 概念 概念 概念
Relational DB Databases Tables Rows Columns
关系型数据库 数据库
ElasticSearch Indices Types Documents Fields
ElasticSearch 索引 类型 文档 字段
面向对象 对象 字段

这里Types理解为表是不太正确的,而且听说,6.2.x版本以后,可能会弃用,这一点,需要注意

2. 操作演示

2.1 建索引—-建索引

PUT /my_index
{
"settings":{
"number_of_shards":3,
"number_of_replicas":0 #因为是单机,这里要设置没有副本,不然会集群黄色
}
}

这里相当于建立了一个索引my_index(可以理解为 MySQL数据库my_index),因为是单机,这里要设置没有副本,不然会集群黄色

2.2 建立表?使用mapping

这个mapping有点类似我们定义MySQL的数据库表结构的时候,需要指定每个字段的名字,其数据类型一样。

当然,这个定义过程,也指明了这个表结构一共含有多少个字段了。

对于ES而言,就相当于指定了一个document有多少field,每个field的数据类型,注意,这个比MySQL定义表过程,还多了一个有用的操作,就是指定每个字段可用的分析器(analyzer). 当然,不指定的话,就是采用默认的standard analyzer,当然你也可以指定某个字段不需要分析器(not_analyzed).

PUT /my_index
{
"mappings": {
"mytable": { # 表名称
"properties": {
"name": { # name字段
"type": "text", # 类型text
"analyzer": "standard" # 这个字段使用的分析器是标准分析器
},
"age": { # age年龄字段
"type": "text", # 类型text
"analyzer": "standard" # 这个字段使用的分析器是标准分析器
}
}
}
}
}

这里报错

{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [my_index/niotLCjpTmCIjCsTivAMcg] already exists",
"index_uuid": "niotLCjpTmCIjCsTivAMcg",
"index": "my_index"
}
]
,
"type": "resource_already_exists_exception",
"reason": "index [my_index/niotLCjpTmCIjCsTivAMcg] already exists",
"index_uuid": "niotLCjpTmCIjCsTivAMcg",
"index": "my_index"
}
,
"status": 400
}

刚刚开始在这里出现好几个问题,其中最多的是

"type": "mapper_parsing_exception",
"reason": "No handler for type [string] declared on field [name]"

原因是字段类型,不支持string了,我这个版本是6.2.x

2.3 版本6.2.x的字段类型

这里参考官网
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
字段数据类型
Elasticsearch为文档中的字段支持许多不同的数据类型:

2.3.1 核心数据类型

  • 字符串 string类型取消了
    textkeyword
    1. keyword:存储数据时候,不会分词建立索引
    2. text:存储数据时候,会自动分词,并生成索引(这是很智能的,但在有些字段里面是没用的,所以对于有些字段使用text则浪费了空间)
  • 数字数据类型
    longintegershortbytedoublefloathalf_floatscaled_float
  • 日期数据类型
    date
  • 布尔数据类型
    boolean
  • 二进制数据类型
    binary
  • 范围数据类型
    integer_rangefloat_rangelong_rangedouble_rangedate_range
  • 复杂的数据类型,这里不罗列,去官网看

2.4 解决2.2的问题(建索引的时候建立映射(类比mysql建立数据库的同时建表))

这样新建(新建数据库中的表)会出错,是不是建立index的时候,就要建立表呢?

DELETE /my_index

PUT /my_index
{
"settings":{
"number_of_shards":3,
"number_of_replicas":0
},
"mappings":{
"student":{
"properties":{
"name":{
"type":"text",
"analyzer": "standard"
},
"age":{
"type":"text",
"analyzer": "standard"
}
}

}
}
}

这样做果然成功了,

{
"acknowledged": true,
"shards_acknowledged": true,
"index": "my_index"
}

2.5 添加数据

我们尝试添加数据

POST /my_index/student/1
{
"name" : "John",
"age" : "20"
}

添加成功

{
"_index": "my_index",
"_type": "student",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
}
,
"_seq_no": 0,
"_primary_term": 1
}

2.6 删除数据

DELETE /my_index/student/1

2.7 删除type

删除type有两种选择:

  1. 重新设置index。
  2. 删除type下的所有数据。

从6开始一个索引只能有一个type
下个版本会移除type

2.8 删除索引

DELETE /my_index

3. 总结

3.1 settings和mappings总结

1.settings是修改分片和副本数的

2.mappings是修改字段和类型的。

2.1 ES的mapping如何用?什么时候需要手动,什么时候需要自动?

  Mapping,就是对索引库中索引的字段名称及其数据类型进行定义,类似于mysql中的表结构信息。不过es的mapping比数据库灵活很多,它可以动态识别字段。一般不需要指定mapping都可以,因为es会自动根据数据格式识别它的类型,如果你需要对某些字段添加特殊属性(如:定义使用其它分词器、是否分词、是否存储等),就必须手动添加mapping。

  我们在es中添加索引数据时不需要指定数据类型,es中有自动影射机制,字符串映射为text,数字映射为long。通过mappings可以指定数据类型是否存储等属性。

 2.2  我们不给index指定mapping或不进行settings设置,其实在很多时候也工作的很好。但是,对于操作的数据对象,我们自己了解的信息一定不会比ES系统猜测的信息全和准确。所以,我们自己在工程应用中,最好还是要自己给自己的索引做settings和mappings的设置。

3.2 模板

PUT /my_index                               # 索引名称 相当于mysql数据库
{
"settings": {
"number_of_shards":3, # 配置主分片
"number_of_replicas":0, # 配置副分片,单机请设置为0
"analysis": {
"analyzer": { #配置分析器
"csh_analyzer": { #分析器的名字是csh_analyer,这个是系统没有的,我自己定义的一个,可以取一个不和已有的分析器重名的名字
"type": "standard", #这个分析器的类型是基于系统自带的标准的standard分析器
"stopwords": "_english_" #禁用词,或者说无效词范围定义来自_english_列表
}
}
}
},
"mappings": {
"user_table": { #定义test索引下的一个type为user_table,相当于msql表名
"properties": { #开始定义这个type的属性值(也可以用fields)
"first_name": { #字段名为first_name
"type": "string", #数据类型为string
"index": "not_analyzed" #属性控制怎样索引字符结合属性analyzer,取值 analyzed(默认) not_analyzed no 参考:https://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/mapping-intro.html
"analyzer": "standard"   #分析器用系统默认的standard
},
"last_name": { #字段名字为last_name
"type": "string", #字段类型为string
"analyzer": "csh_analyzer" #分析器为自定义的csh_analyzer
},
"age": { #字段名字为age年龄
"type": "string", #字段类型
"analyzer": "csh_analyzer" #分析器为自定义的csh_analyzer
}
}
}
}
}

https://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/_finding_your_feet.html