Elasticsearch Mapping 详解

 

 

什么是Mapping?

这个Mapping 对应关系型数据库的schema的定义,作用如下:

  • 定义索引中的字段的名字
  • 定义字段的数据类型,例如字符串、数字、布尔类型...
  • 字段、倒排索引的相关配置,Analyzed or Not Analyzed, Analyzer

Mapping 会把JSON文档映射成Lucene 所需要的扁平格式

一个Mapping属于一个索引的Type

  • 每个文档都属于一个Type
  • 一个Type有一个Mapping 定义
  • 7.0开始,不需要再Mapping定义中指定type信息

Elasticsearch 中当创建索引的时候,Dyamic Mapping 默认会根据索引中的字段,创建mapping 的数据类型。

Elasticsearch中的字段类型有

简单类型

  • Text/Keyword
  • Date
  • integer / Floating
  • Boolean
  • IPV4 & IPV6

复杂类型

  • 对象类型 / 嵌套类型

特殊类型

  • geo_poing & geo_shape / percolator

什么是Dynamic Mapping?

  • 在写入文档的时候,如果索引不存在,会自动创建索引
  • Dynamic Mapping的机制,使得我们无需手动定义Mapping。Elasticsearch会自动根据文档信息,推算出字段的类型
  • 但是有的时候推算的不准,例如地理位置信息
  • 当类型设置的不对时,会导致一些功能无法正常运行,例如Range 查询

类型的自动识别

JSON类型 Elasticsearch类型 字符串

匹配日期格式,设置成Date

配置数字设置为float或者long,该选项默认关闭

设置成text,并且增加keyword 子字段

布尔值 boolean 浮点数 float 整数 long 对象 Object 数组 由第一个非空数值的类型所决定 空值 忽略

//dynamic mapping, 推断字段的类型
PUT mapping_test/_doc/1
{
  "uid":"123",
  "isVip":false,
  "isAdmin":"true",
  "age":19,
  "heigh":180
}
// 查看Maping 推断的类型
GET mapping_test/_mapping

能否更改Mapping的字段类型

两种情况

  • 新增加字段
    • Dynamic 设为Strict时,文档写入失败
    • Dynamic 设为false时,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
    • Dynamic 设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
  • 对已有字段,一旦已经有数据写入,就不再支持修改字段的定义
  • 如果希望改变字段的类型,必须Reindex APi,重建索引
    • Lucene 实现的倒排索引,一旦生成后,就不允许修改

原因

  • 如果修改了字段的数据类型,会导致已被索引的属于无法被搜索
  • 但是如果是增加新的字段,就不会有影响

控制Dynamic Mappings

 “true”“false”“strict”
文档可索引YESYESNO
字段可索引YESNONO
Mapping被更新YESNONO

 

 

 

 

 

当dynamic被设置成false时候,存在新增字段的数据写入,该数据可以被索引,但是新增字段被丢弃

当设置成Strict模式的时候,数据写入直接出错

 

操作示例

//mapping 
// 字段的数据类型

// 写入文档,查看Mapping,验证自动推断
PUT mapping_test/_doc/1
{
  "firstName":"Chan",
  "lastName":"Jackie",
  "loginDate":"2018-07-24T10:29:48.103Z"
}

// 查看Maping 
GET mapping_test/_mapping
// 删除索引
DELETE mapping_test
// 查看es 索引
GET _cat/indices

//dynamic mapping, 推断字段的类型
PUT mapping_test/_doc/1
{
  "uid":"123",
  "isVip":false,
  "isAdmin":"true",
  "age":19,
  "heigh":180
}
// 查看Maping 推断的类型
GET mapping_test/_mapping

PUT dynamic_mapping_test/_doc/1
{
  "newField":"someValue"
}
POST dynamic_mapping_test/_search
{
  "query": {
    "match": {
      "newField": "someValue"
    }
  }
}
// 修改为dynamic false
PUT dynamic_mapping_test/_mapping
{
  "dynamic": false
}
// 新增字段
PUT dynamic_mapping_test/_doc/10
{
  "annotherField":"someValue"
}
// 查看结果
POST dynamic_mapping_test/_search
{
  "query": {
    "match": {
      "annotherField": "someValue"
    }
  }
}

GET dynamic_mapping_test/_mapping

// 修改为dynamic strict
PUT dynamic_mapping_test/_mapping
{
  "dynamic": "strict"
}
// 新增字段
PUT dynamic_mapping_test/_doc/12
{
  "aa":"someValue"
}
DELETE dynamic_mapping_test

四种不同级别的倒排索引选择

  • docs 记录doc id
  • freqs 记录doc id 和term frequencies
  • positions 记录doc id/term frequencies / term position
  • offsets 记录doc id/term frequencies/term postition / character offects

Text 类型默认记录postions,其他默认docs
记录越多,占用空间越大

// 如何给索引定义mapping
PUT movies
{
  "mappings": {
    // define your mappings here
  }
}

// 不需要索引字段、字段无法被搜索
DELETE user
PUT user
{
  "mappings": {
    "properties": {
      "firstName": {
        "type":"text"
      },
      "lastName": {
        "type": "text"
        
      },
      "mobile": {
        "type": "text",
        "index": false
      }
    }
  }
}
PUT user/_doc/1
{
  "firstName": "Ruan",
  "lastName": "Yiming",
  "mobile": "12345678"
}
POST /user/_search
{
  "query": {
    "match": {
      "mobile":"12345678"
    }
  }
}


// 需要对Null 值实现搜索
PUT user
{
  "mappings": {
    "properties": {
      "firstName": {
        "type":"text"
      },
      "lastName": {
        "type": "text"
        
      },
      "mobile": {
        "type": "keyword",
        "null_value": "NULL"
      }
    }
  }
}
PUT user/_doc/1
{
  "firstName": "Ruan",
  "lastName": "Yiming",
  "mobile": null
}
// 只有keyword类型支持设定NUll_Value
null_value
GET user/_search?q=mobile:NULL
POST /user/_search
{
  "query": {
    "match_all": {}
    }
  }
}

// copy_to 设置 
PUT user
{
  "mappings": {
    "properties": {
      "firstName": {
        "type":"text",
        "copy_to": "fullName"
      },
      "lastName": {
        "type": "text",
        "copy_to": "fullName"
      }
    }
  }
}
PUT user/_doc/1
{
  "firstName": "Ruan",
  "lastName": "Yiming"
}
_all 在7中被copy_to所取代
copy_to 将字段的数值拷贝到目标字段,实现类似_all 的作用
copy_to 的目标字段不会出现在_source中
GET user/_search?q=fullName:(Ruan Yiming)
// 
PUT user/_doc/1
{
  "name": "gnufree",
  "interests": "reading"
}
PUT user/_doc/1
{
  "name": "mark",
  "interests": ["reading","music"]
}
POST /user/_search
{
  "query": {
    "match_all": {}
    }
  }
}
GET user/_mapping

 

### ElasticsearchMapping 的详细介绍 #### 映射的概念及其重要性 MappingElasticsearch 文档结构的定义,类似于关系型数据库中的表模式。它指定了每个字段的数据类型以及如何处理这些数据。这不仅影响到数据存储的方式,也决定了查询性能和功能特性[^1]。 #### 创建索引并定义映射 当创建一个新的索引时,可以通过提供 `mappings` 参数来设定初始映射配置: ```json PUT /my-index-000001 { "settings": { "number_of_shards": 1, "analysis": { ... } }, "mappings": { "_source": {"enabled": true}, "properties": { "title": { "type": "text" }, "date": { "type": "date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"}, "comments": { "type": "nested" } } } } ``` 此示例展示了基本映射设置,其中包含了文本(`text`)类型的 title 字段、日期(`date`)类型的 date 字段 和嵌套对象(nested object) comments[] 数组[^4]。 #### 自动检测与动态模板 如果未显式声明映射,则会启用自动检测机制,默认情况下会对新引入的未知字段应用合理的猜测策略;然而为了更精确控制新增加字段的行为,建议利用动态模板(Dynamic Templates),允许基于正则表达式的匹配规则自定义特定条件下的映射逻辑[^3]。 #### Analyzer 配置详解 Analyzer 负责解析输入字符串成一系列 token (词条), 这对于全文本搜索至关重要。可以在字段级别上指定不同的 analyzers 来优化不同场景下检索效果: * **Index-time analyzer**: 当文档被索引时使用的分词器。 * **Search-time analyzer**: 查询阶段所采用的分词方案。 例如,在下面的例子中设置了两个独立的分析链路——一个是用来建立倒排索引(indexing),另一个则是服务于实际查询(search time): ```json PUT my_index { "mappings": { "properties": { "content": { "type": "text", "analyzer": "ik_max_word", // Index-time analyzer "search_analyzer": "ik_smart" // Search-time analyzer } } } } ``` 这里采用了中文分词插件 IK Analyzer 提供的不同粒度级别的切分方式作为例子[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值