本文介绍: 在ElasticSearch中,没有专门的数组(Array数据类型,但是,在默认情况下,任意一个字段可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组类型各个元素值的数据类型必须相同支持 longintegershortbytedoublefloathalf_floatscaled_float。通用的ISO日期格式,其中日期部分是必需的,时间部分是可选的。对于整数类型byteshortintegerlong)而言,我们应该选择这是足以使用最小类型

版本:Elasticsearch 6.2.4。

Mapping类似于数据库中的表结构定义,主要作用如下

Mapping完整内容可以分为部分内容

自动Mapping

如果没有手动设置Mapping,Elasticsearch默认自动解析出类型,且每个字段第一次出现的为准。

下面我们先看一下Elasticsearch默认创建的Mapping什么样的。

首先我们创建一个索引:

PUT /user/

查询索引信息

GET /user

结果

{
  "user": {
    "aliases": {},
    "mappings": {},
    "settings": {
      "index": {
        "creation_date": "1540044686190",
        "number_of_shards": "5",
        "number_of_replicas": "1",
        "uuid": "_K5b8w7jRiuthf7QeQZhdw",
        "version": {
          "created": "5060299"
        },
        "provided_name": "user"
      }
    }
  }
}

增加一条数据

PUT /user/doc/1
{
  "name":"Allen Yer",
  "job":"php",
  "age":22
}

PUT /user/doc/2
{
  "name":"Allen Yer",
  "job":0,
  "age":22
}

查询数据是否新增成功

GET /user/doc/_count

结果

{
  "count": 2,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  }
}

count为2,说明新增成功然后我们查询mapping :

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

发现自动为每个字段设置了类型:

大家可以把索引删掉,将新增数据调整为先新增第2条,再新增第一条,发现报错了:

DELETE /user

PUT /user/doc/2
{
  "name":"Allen Yer",
  "job":0,
  "age":22
}

PUT /user/doc/1
{
  "name":"Allen Yer",
  "job":"php",
  "age":22
}

报错

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse [job]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse [job]",
    "caused_by": {
      "type": "number_format_exception",
      "reason": "For input string: "php""
    }
  },
  "status": 400
}

也能说明第一次为主以字段第一次的值类型为准。这也说明默认创建mapping可能不是我们想要的,这就需要手动创建mapping,好处有:

手动创建mapping

这次我们删掉mapping,并手动创建一个

DELETE /user

PUT /user/
{
    "mappings": {
      "doc": {
        "properties": {
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "age": {
            "type": "long",
            "index": false
          },
          "job": {
            "type": "keyword"
          },
          "intro":{
            "type":"text"
          },
          "create_time": {
            "type": "date", 
            "format": "epoch_second"
        }
        }
     }
  }
}

字段类型说明

注意mapping生成后是不允许修改(包括删除)的。所以需要提前合理的的定义mapping。

字段类型

Elasticsearch支持文档中字段的许多不同数据类型

普通数据类型

字符串类型

text 和 keyword2种 。其中 text 支持分词,用于全文搜索keyword 不支持分词,用于聚合排序。在旧的ES里这两个类型由string表示

如果安装了IK分词插件,我们可以为text类型指定IK分词器。一般来说,对于字符串类型,如果:

1) 模糊搜索+精确匹配,一般是name或者title字段:

"name": {
        "type": "text",
        "analyzer": "ik_smart",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }

2) 模糊搜索,一般是内容详情字段:

"content": {
        "type": "text",
        "analyzer": "ik_smart"
      }

3) 精确匹配:

"name": {
        "type": "keyword"
      }

4) 不需要索引:

"url": {
        "type": "keyword",
        "index": false
      }
数字类型

支持 longintegershortbytedoublefloathalf_float,scaled_float。具体说明如下

符号的64位整数,其最小值-2^63最大值(2^63)-1

符号的32位整数,其最小值-2^31最大值(23^1)-1

符号的16位整数,其最小值为-32,768,最大值为32,767。

符号的8位整数,其最小值为-128,最大值为127。

精度64位IEEE 754浮点数

精度32位IEEE 754浮点数

精度16位IEEE 754浮点数

缩放类型的的浮点数。需同时配置缩放因子(scaling_factor)一起使用

对于整数类型(byteshortintegerlong)而言,我们应该选择这是足以使用最小的类型。这将有助于索引和搜索有效

对于浮点类型(float、half_float和scaled_float),-0.0+0.0不同的值,使用term查询查找-0.0不会匹配+0.0,同样range查询中上边界-0.0不会匹配+0.0,下边界+0.0不会匹配-0.0

其中scaled_float,比如价格只需要精确到分,price57.34的字段缩放因子为100,存起来就是5734优先考虑使用缩放因子的scaled_float浮点类型。

示例

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "status": {
          "type": "byte"
        },
        "year": {
          "type": "short"
        },
        "id": {
          "type": "long"
        },
        "price": {
          "type": "scaled_float",
          "scaling_factor": 100
        }
      }
    }
  }
}
日期类型

类型为 date 。

JSON本身是没有日期类型的,因此Elasticsearch中的日期可以是:

在Elasticsearch内部,日期类型会被转换为UTC(如果指定时区)并存储为long类型表示的毫秒时间戳。

日期类型可以使用使用format自定义默认缺省值:"strict_date_optional_time||epoch_millis"

"postdate": {
      "type": "date",
      "format": "strict_date_optional_time||epoch_millis"
    }

format 有很多内置类型,这里列举部分说明

通用的ISO日期格式,其中日期部分是必需的,时间部分是可选的。例如 “2015-01-01″或”2015/01/01 12:10:30″。

13位毫秒时间

10位普通时间戳

其中strict_开头的表示严格的日期格式,这意味着,年、月、日部分必须具有前置0。

更多日期格式详见:
https://www.elastic.co/guide/…

当然也可以自定义日期格式例如

"postdate":{
      "type":"date",
      "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
    }

注意:如果新文档的字段的值与format里设置的类型不兼容,ES会返回失败。示例:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type": "date",
          "format":"epoch_millis"
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "date":1543151405000
}
PUT my_index/_doc/2
{
  "date":1543151405
}
PUT my_index/_doc/3
{
  "date":"2018-11-25 21:10:43"
}
GET my_index/_doc/_search

第3条数据插入失败,因为只接受长整数的时间戳,字符串类型的日期是不匹配的。第2条的值只有10位数,虽然值是不正确的,但是在epoch_millis取值范围内,所以也是成功的。

布尔类型

类型为 boolean 。

二进制类型

类型为 binary 。

范围类型

integer_rangefloat_range,long_rangedouble_rangedate_range

复杂类型

在ElasticSearch中,没有专门的数组(Array)数据类型,但是,在默认情况下,任意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组类型的各个元素值的数据类型必须相同。在ElasticSearch中,数组是开箱即用的(out of box),不需要进行任何配置,就可以直接使用。,例如:

字符型数组: [ "one", "two" ]
整型数组:[ 1, 2 ]
数组型数组:[ 1, [ 2, 3 ]] 等价于[ 1, 2, 3 ]

object 对于单个JSON对象。JSON天生具有层级关系文档可以包含嵌套的对象。

nested 对于JSON对象的数组

Geo数据类型

geo_point 对于纬度/经度点

  • Geo-Shape数据类型

geo_shape 对于像多边形这样的复杂形状

专用数据类型

  • IP数据类型

ip 用于IPv4和IPv6地址

completion 提供自动完成建议

token_count 计算字符串中的标记

murmur3 在索引时计算值的哈希值并将它们存储在索引中

接受来自querydsl的查询

为同一索引中的文档定义父/子关系

多字段

不同目的以不同方式索引相同字段通常很有用。例如,string可以将字段映射为text用于全文搜索的keyword字段,以及用于排序聚合的字段。或者,您可以使用standard分析仪, english分析仪和 french分析仪索引文本字段。

元字段

_all

该字段用于在没有指定具体字段的情况下进行模糊搜索,可以搜索全部字段的内容

原理是将所有字段的内容视为字符串,拼在一起放在一个_all字段上,但这个字段默认是不被存储的,可以被搜索。在query_string与 simple_query_string查询(Kibana搜索框用的这种查询方式)默认也是查询_all字段。

6.x 版本被默认关闭

相关设置

PUT my_index
{
  "mappings": {
    "my_type": {
      "_all": {
        "enabled": true,
        "store": false
      },
      "properties": {}
    }
  },
  "settings": {
    "index.query.default_field": "_all" 
  }
}

上述配置在5.x版本是默认配置:

  • 默认开启 _all 字段
  • 默认不存储 _all 字段
  • 默认搜索 _all 字段

如果从CPU性能磁盘空间考虑,可以考虑可以完全禁用基于每个字段自定义_all字段。

假设_all字段被禁用,则URI搜索请求、 query_stringsimple_query_string查询将无法将其用于查询。我们可以将它们配置为其他字段:通过定义 index.query.default_field 属性

_source

这个字段用于存储原始的JSON文档内容,本身不会被索引,但是搜索的时候返回。如果没有该字段,虽然还能正常搜索,但是返回内容知道对应的是什么

示例:

GET /user/doc/_search?q=name

结果

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "user",
        "_type": "doc",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "name": "this is test name",
          "age": 22,
          "job": "java",
          "intro": "the intro can not be searched by singal",
          "intro2": "去朝阳公园",
          "create_time": 1540047542
        }
      }
    ]
  }
}

搜索结果就包含_source字段,存储的是原始文档内容。如果被禁用,只知道有匹配内容,但是无法知道返回的是什么。所以需要谨慎关闭该字段。

如果想禁用该字段,可以在创建Mapping的时候设置_:

{
  "mappings": {
    "_doc": {
      "_source": {
        "enabled": false
      }
    }
  }
}

_type

ElasticSearch里面有 index 和 type 的概念:index称为索引,type为文档类型,一个index下面有多个type,每个type的字段可以不一样。这类似于关系数据库databasetable概念

但是,ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。所以后来ElasticSearch团队去掉type,于是在6.x版本为了向下兼容,一个index只允许有一个type。

该字段再在6.0.0中弃用。在Elasticsearch 6.x 版本中创建的索引只能包含单个type。在5.x中创建的含有多个type的索引将继续像以前一样在Elasticsearch 6.x中运行。type 将在Elasticsearch 7.0.0中完全删除

原文地址:https://blog.csdn.net/u011807844/article/details/134739732

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_47452.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注