Elasticsearch中的mapping与字段类型(Field Type)

原创
2021/10/10 23:14
阅读数 225

本文以ES7.7版本为基础.

推荐一个他人在用的基于nodejs的web管理界面: elasticsearch-head , 我仍然在用kibana

查看所有index

GET /_cat/indices

indices 是index的复数形式.

查看索引的定义 mapping

先看下官方演示数据 flights data的结构:

GET /kibana_sample_data_flights/_mapping

执行结果:

{
  "kibana_sample_data_flights" : {
    "mappings" : {
      "properties" : {
        "AvgTicketPrice" : {
          "type" : "float"
        },
        "Cancelled" : {
          "type" : "boolean"
        },
        "Carrier" : {
          "type" : "keyword"
        },...
        "DestLocation" : {
          "type" : "geo_point"
        },...
        "DistanceMiles" : {
          "type" : "float"
        },
        "FlightDelay" : {
          "type" : "boolean"
        },
        "FlightDelayMin" : {
          "type" : "integer"
        },....
        "FlightTimeHour" : {
          "type" : "keyword"
        },
        "FlightTimeMin" : {
          "type" : "float"
        },
        "Origin" : {
          "type" : "keyword"
        },
        "OriginAirportID" : {
          "type" : "keyword"
        },...
        "OriginCountry" : {
          "type" : "keyword"
        },
        "OriginLocation" : {
          "type" : "geo_point"
        },
        "OriginRegion" : {
          "type" : "keyword"
        },
        "OriginWeather" : {
          "type" : "keyword"
        },
        "dayOfWeek" : {
          "type" : "integer"
        },
        "timestamp" : {
          "type" : "date"
        }
      }
    }
  }
}

再看下我们之前定义的一个index:

GET twitter/_mapping

执行结果:

{
  "twitter" : {
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "age" : {
          "type" : "long"
        },
        "city" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "country" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "location" : {
          "type" : "geo_point"
        },
        "message" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "province" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "uid" : {
          "type" : "long"
        },
        "user" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

上面的命令mapping就是我们今天要学习的mapping的一部分.

mapping

mapping是定义一个文档及其栏位(fields)的过程, 存储并被索引. 比如, 我们可以使用mapping去做这些事:

  • 哪些字符串类型的栏位需要使用全文索引
  • 哪些栏位包含数字(numbers), 日期(dates), 地里位置(geolocations)
  • 定义日期类型值的格式
  • 自定义规则, 以控制动态添加的栏位(dynamically added fields)

一个mapping定义包含:

  • 元字段(Meta-fields)

元字段用于自定义如何处理文档的元数据, 比如: _index, _id, _source

  • Fields or properties

mapping包含了一个文档的字段或属性的列表.

7.0版本之前, mappings 定义中还包含了一个type. 更多参考Removal of mapping types

参考官方文档

字段的数据类型

字段类型包含以下几种:

通常我们会以不同的方式索引同一个字段, 比如一个字符串类型的字段会被作为text类型以用于分词后的全文索引, 也会被作为keyword类型用于关键词全词匹配或聚合. 也可以使用标准分析器(standard analyzer)、英语分析器(english analyzer)和法语分析器(french analyzer)为字符串字段编制索引。

这就是multi-fields的用途, 大多数类型都可以通过fileds参数来支持它.

防止mapping爆炸

栏位数量不要超过index.mapping.total_fields.limit的设置值(默认是1000), 以避免导致内存不足或者难以恢复(recover)的情况.

这个与mysql每个表栏位数量限制类似, 虽然mysql最多可以支持4096个栏位, 但是过多的栏位可能会导致一个16kb的page无法容纳至少2条数据, 从而不符合B-Tree的要求.

更多的参考官方文档.

明确定义mapping

虽然ES支持动态mapping(dynamic mapping, 自动把新的栏位名称添加到索引), 但是为了更精确的定义栏位类型, 还是建议给出明确的定义.

对于已经存在的index, 无法修改栏位类型(但是可以添加栏位), 只能删除index, 然后重新定义, 再导入数据

创建一个索引的mapping:

PUT /my-index
{
  "mappings": {
    "properties": {
      "age":    { "type": "integer" },
      "email":  { "type": "keyword"  },
      "name":   { "type": "text"  }
    }
  }
}

向一个mapping添加栏位:

PUT /my-index/_mapping
{
  "properties": {
    "employee_id": {
      "type": "keyword",
      "index": false
    }
  }
}
PUT /my-index/_mapping
{
  "properties": {
    "emp_no": {
      "type": "keyword"
    }
  }
}

修改栏位

  • 栏位类型修改: 不支持, 只能重建索引.
  • 栏位更名: 建议使用别名alias

查看一个索引的mapping定义

GET my-index/_mapping

查看一个索引的mapping中的某一个栏位的定义:

GET my-index/_mapping/field/employee_id
展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部