【ElasticSearch-基础篇】Mapping结构

2024-01-09 10:58:49

在这里插入图片描述

1.什么是Mapping

Mapping 类似 mysql 中的 schema 的定义
用于定义索引属性字段的名称、字段的数据类型 (如 text , long , keyword…)、字段的倒排索引相关配置
一个Mapping 属于一个索引的Type、每个文档都属于一个Type
es7.0开始, 在Mapping中不需要指定 Type信息, 因为7.0之后只有_doc Type

2.自动创建Mapping

当我们去创建一个 索引的时候 未指定 mapping , es会默认帮这个索引创建一个 mapping
例:创建一个索引testmapping

创建一个空索引:

PUT testmapping

创建成功:

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

查询该索引mapping信息:

GET testmapping/_mapping

返回结果:

{
  "testmapping" : {
    "mappings" : { }
  }
}

此时可以看到ES为我们创建了一个空mapping的索引,如果我们在创建索引的时候指定字段,ES也会生成我们指定的字段类型,或者默认的类型

创建名为user的索引,并指定字段及字段类型

PUT /user
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "language": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "publish_time": {
        "type": "date",
        "format": "yyy-MM-dd"
      }
    }
  }
}

获取user的mapping信息

GET user/_mapping

{
  "user" : {
    "mappings" : {
      "properties" : {
        "language" : {
          "type" : "keyword"
        },
        "price" : {
          "type" : "double"
        },
        "publish_time" : {
          "type" : "date",
          "format" : "yyy-MM-dd"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        }
      }
    }
  }
}

动态映射(dynamic mapping)

关系型数据库: 先创建表 => 指定字段和字段类型 => 数据写入表
在ES中,索引就相当于表,文档就相当于记录,文档里面的字段就相当于表的字段,字段同样有数据类型。mapping就用来定义文档有哪些字段,这些字段如何存储和索引。

ES与关系型数据库不同之处在于: 其不需要先定义表结构,而可以根据写入文档的内容,来推断字段和数据类型,创建索引结构,这就是dynamic mapping,动态映射的由来。这提供了极大的灵活性。
注:一个索引的字段数量有上限的,超过上限就会报错(默认单个索引创建最大1000个字段)

dynamic参数设置:
按dynamic值,可分为下面三种模式

动态模式(dynamic:true),根据输入文档的内容,自动推断字段和类型,创建mapping
非动态模式(dynamic:false),无法根据输入文档的内容,自动创建mapping,需要手动创建mapping
严格模式(dynamic:strict),同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在mapping中,依然可以存储和读取,但是该字段不在mapping中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。

1.动态模式

直接对一个不存在的索引插入一条数据

POST dynamictrue/_doc
{
  "name": "张三",
  "age": 15
}

插入成功,获取该索引的mapping信息

GET dynamictrue/_mapping

{
  "dynamictrue" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

在动态模式下,ES会根据插入的数据自动生成对应的字段类型,也可以通过动态模板(dynamic template)来覆盖这个规则,实现自定义推测规则,具体可以参考ES官网

1.1动态模式下索引文档

GET dynamictrue/_search

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamictrue",
        "_type" : "_doc",
        "_id" : "ulYk54wBAEWV3dbHq4Dj",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论: 动态模式下索引文档是有数据返回的

1.2动态模式下索引字段

-- 查询当前索引下age是15的数据
GET dynamictrue/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "age": {
              "value": 15
            }
          }
        }
      ]
    }
  }
}

返回值:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamictrue",
        "_type" : "_doc",
        "_id" : "ulYk54wBAEWV3dbHq4Dj",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论: 动态模式下索引字段也是可以的

1.3动态模式下变更Mapping

新增一个字段
POST dynamictrue/_doc
{
  "addr": "地址"
}

成功新增名为addr的字段
GET dynamictrue/_mapping

{
  "dynamictrue" : {
    "mappings" : {
      "properties" : {
        "addr" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

2.非动态模式

新建一个索引(dynamicfalse)并设置dynamic为false

PUT dynamicfalse
{
  "settings": {
    "index": {
      "number_of_shards": "5",
      "number_of_replicas": "1"
    }
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "long"
      }
    }
  }
}

查询索引(dynamicfalse)的mapping信息

GET dynamicfalse/_mapping

{
  "dynamicfalse" : {
    "mappings" : {
      "dynamic" : "false",
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}

此时可以看到返回结果中dynamic已经被设置成false

此时我们对该索引新增一条数据

POST dynamicfalse/_doc
{
  "name": "张三",
  "age": 15
}

2.1非动态模式下索引文档

GET dynamicfalse/_search

查询结果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamicfalse",
        "_type" : "_doc",
        "_id" : "hFYi54wBAEWV3dbHdYDM",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论: 非动态模式下索引文档是有数据返回的

2.2非动态模式下索引字段

GET dynamicfalse/_search
{
  "query": {
    "match": {
      "age": 15
    }
  }
}

返回结果:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamicfalse",
        "_type" : "_doc",
        "_id" : "z1a154wBAEWV3dbHQYzt",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论: 非动态模式下索引字段是可以的,但是只针对查询在mapping中存在的字段生效,如果字段不存在mapping,无法生效,请往下看↓

2.3非动态模式下变更Mapping

在当前索引中插入一个addr字段的数据
POST dynamicfalse/_doc
{
  "addr": "地址"
}

插入成功后,查询当前索引mapping信息
GET dynamicfalse/_mapping

{
  "dynamicfalse" : {
    "mappings" : {
      "dynamic" : "false",
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}
可以发现非动态模式下新增的字段并没有在mapping中生成

此时查询当前索引中数据

GET dynamicfalse/_search

返回数据如下:
{
  "took" : 537,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamicfalse",
        "_type" : "_doc",
        "_id" : "cVa654wBAEWV3dbHtI3g",
        "_score" : 1.0,
        "_source" : {
          "addr" : "地址"
        }
      },
      {
        "_index" : "dynamicfalse",
        "_type" : "_doc",
        "_id" : "z1a154wBAEWV3dbHQYzt",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}
此时可以发现addr为地址的数据已经成功插入到了当前索引中

此时再根据addr字段索引数据

GET dynamicfalse/_search
{
  "query": {
    "match": {
      "addr": "地址"
    }
  }
}

返回结果如下:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

结论: 非动态模式下变更mapping是无法在mapping中生成的,新增的数据虽然可以存储,但是无法被新增的字段索引,只能根据文档索引或者已存在mapping中的字段索引所带出

3.严格模式

新建一个索引(dynamicfalse)并设置dynamic为strict

PUT dynamicstrict
{
  "settings": {
    "index": {
      "number_of_shards": "5",
      "number_of_replicas": "1"
    }
  },
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "long"
      }
    }
  }
}

查询当前索引(dynamicstrict)的mapping信息

GET dynamicstrict/_mapping

{
  "dynamicstrict" : {
    "mappings" : {
      "dynamic" : "strict",
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}

新增一条数据

POST dynamicstrict/_doc
{
  "name": "张三",
  "age": 15
}

3.1严格模式下索引文档

GET dynamicstrict/_search

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "dynamicstrict",
        "_type" : "_doc",
        "_id" : "-1bS54wBAEWV3dbH3I99",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论: 严格模式下索引文档是可以的

3.2严格模式下索引字段

GET dynamicstrict/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  }
}

返回结果如下:
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "dynamicstrict",
        "_type" : "_doc",
        "_id" : "-1bS54wBAEWV3dbH3I99",
        "_score" : 0.5753642,
        "_source" : {
          "name" : "张三",
          "age" : 15
        }
      }
    ]
  }
}

结论:严格模式下索引mapping中存在的字段也是可以的

3.3严格模式下变更Mapping

POST dynamicstrict/_doc
{
  "addr": "地址"
}

返回报错信息如下:
{
  "error" : {
    "root_cause" : [
      {
        "type" : "strict_dynamic_mapping_exception",
        "reason" : "mapping set to strict, dynamic introduction of [addr] within [_doc] is not allowed"
      }
    ],
    "type" : "strict_dynamic_mapping_exception",
    "reason" : "mapping set to strict, dynamic introduction of [addr] within [_doc] is not allowed"
  },
  "status" : 400
}

结论: 严格模式下无法新增字段,此模式可以用于在工作中防止自己的索引字段被人修改

文章来源:https://blog.csdn.net/qq_42890164/article/details/135450323
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。