在Elasticsearch7.0之前,我们将每个文档存储在index中,并分配一个映射类型,映射类型用于标识索引的文档或实体的类型,比如:在一个register 索引中,我们可能设置user类型和information类型。在user类型中可能存在username、age、sex等字段,information中可能存在username、password、createtime等字段,我们在检索的时候,在url中可以同时指定检索的type,比如
GET register/user,information/_search
进行查询。
但是在Elasticsearch7.0以后中放弃了mapping中type的设置,例如,我们如果想通过如下的方式指定doc的字段属性时,就会抛出异常
{
"mappings":{
"doc":{
"properties":{
"title":{
"type":"text",
"similarity":"BM25"
}
}
}
}
}
异常信息如下:
{"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters: [doc : {properties={title={similarity=BM25, type=text}}}]"}],"type":"mapper_parsing_exception","reason":"Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [doc : {properties={title={similarity=BM25, type=text}}}]","caused_by":{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters: [doc : {properties={title={similarity=BM25, type=text}}}]"}},"status":400}
大致的意思是无法解析_doc。
很多地方将ElasticSearch与数据库类比,比如将index看作数据库,type看作数据库表,id看作表结构中的主键。但是,在内部的机制中却有不同,在同一个数据库中,不同的表的字段可以名称相同,类型不同,但是在ES中,由于在不同映射类型中具有相同名称的字段在内部由相同的Lucene字段支持,因此在相同的索引中,如果给不同type设置相同filed,但是filed的属性不同的话,在操作比如删除时,就可能会删除失败。除此之外,存储在同一索引中具有很少或没有共同字段的不同实体会导致数据稀疏,并影响Lucene有效压缩文档的能力。因此在es7的时,废除类mapping types 的设置。在7.0到8.0之间,我们可以通过
include_type_name=false
指定是否使用mapping types。(7.0默认是true,7.0-8.0默认是false,true 开启,false关闭),比如
PUT index?include_type_name=false
{
"mappings": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}
比如上面举的例子,将user和information单独设置成两个index,而不是将他们两个放到同一个index中。在es中indices中,index之间是相互独立的,因此对于里面的字段将不会引起冲突。这样主要包含两个好处
映射类型直接设置在mappings下,不需要type的名称
PUT index
{
"mappings": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}
PUT index/_mappings
"properties": {
"bar": {
"type": "text"
}
}
}
获取mappings的方式
GET index/_mappings
在es7.0必须通过{index}/_doc 来自动创建id,通过{index}/_doc/{id}指定id
PUT index/_doc/1
{
"foo": "baz"
}
类似的get 和 delete apis使用{index}/_doc/{id}:
GET index/_doc/1
说明,在7.0以后,_doc替代document type, 将在index,get, delete api中一直使用,并且在ES8.0中一直保持。
对于同时包含类型和端点名(如_update)的API路径,在7.0中端点将立即跟随索引名:
POST index/_update/1
{
"doc" : {
"foo" : "qux"
}
}
GET /index/_source/1
类型也不应该再出现在请求体中。下面的批量索引示例省略了URL和单个批量命令中的类型:
POST _bulk
{ "index" : { "_index" : "index", "_id" : "3" } }
{ "foo" : "baz" }
{ "index" : { "_index" : "index", "_id" : "4" } }
{ "foo" : "qux" }
在调用诸如_search、_msearch或_explain之类的搜索API时,URL中不应该包含类型。此外,_type字段也不应该用于查询、聚合或脚本。在回复的内容中,为了避免对解析结果造成异常,_type字段将保留在回复的结果中。但是在ES8.0中,_type字段将被彻底去除。
es7官方指南