ES-DynamicMapping、文档字段类型

Dynamic Mapping

什么是Dynamic Mapping

   在写入文档时候,如果所有不存在,会自动创建索引。

  Dynamic Mapping的机制,使得我们无需手动自定义Mappings。Elasticsearch会自动根据文档信息,推算出自动的类型。

  但是有时候回推算不正确,例如地理位置信息,当类型如果不对时,会导致一些功能无法正常运行,例如Range查询。

类型的自动识别

JSON类型Elasticsearch类型
字符串1.匹配日期格式,设置成Date
2.配置数字设置为float/long,配置默认关闭
3.设置为Text,并且增加keyword子自动
布尔值boolean
浮点数float
整数long
对象object
数组由第一个非空数值的类型所决定
空值忽略

查询Mapping

  kibana执行以下:

get movies/_mappings

  返回结果:

{
  "movies" : {
    "mappings" : {
      "properties" : {
        "@version" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "genre" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "id" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "year" : {
          "type" : "long"
        }
      }
    }
  }
}

更改Mapping字段类型

  有两种情况:

情况
新增字段1.Dynamic设为true,一旦有新增字段的文档写入,Mapping也同时更新

2.Dynamic设置为false,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中

3.Dynamic设置成Strict,文档写入失败
已有字段一旦已经有数据写入,就不再支持修改字段定义,Lucene实现的倒排序索引,一旦生成后,就不允许修改

  原因:

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

  Dynamic 使用

  • true:遇到陌生字段 进行dynamic mapping
  • false:遇到陌生字段,忽略
  • strict:遇到陌生字段,报错
put mapping_test
{
  "mappings":{
    "dynamic":"strict",
    "properties":{
      "title":{
        "type":"text"
      },
      "address":{
        "type":"object",
        "dynamic":"true"
      },
      "year":{
        "type":"long"
      }
    }
  }
}

  查询mapping

get mapping_test/_mappings

  返回结果:

{
  "mapping_test" : {
    "mappings" : {
      "dynamic" : "strict",
      "properties" : {
        "address" : {
          "type" : "object",
          "dynamic" : "true"
        },
        "title" : {
          "type" : "text"
        },
        "year" : {
          "type" : "long"
        }
      }
    }
  }
}

数据类型

Elasticsearch支持多种数据类型,这些数据类型可以分为两类:核心数据类型和复杂数据类型。

字符串(String)

字符串(String):字符串是最常用的数据类型,可以用于存储文本信息。Elasticsearch提供了两种特殊的字符串类型:text和keyword。

  1. text:text类型的字符串主要用于全文搜索,它会使用分词器对字符串进行分词,然后将分词后的词项存储在索引中。这使得text类型的字符串可以进行模糊匹配、短语搜索等高级搜索功能。然而,由于进行了分词,text类型的字符串不能直接用于排序和聚合操作。
  2. keyword:keyword类型的字符串主要用于精确匹配,它不会使用分词器对字符串进行分词,而是直接将原始字符串存储在索引中。这使得keyword类型的字符串可以直接用于排序和聚合操作。然而,由于没有进行分词,keyword类型的字符串不能进行模糊匹配和短语搜索等高级搜索功能。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "standard"
      },
      "email": {
        "type": "keyword"
      }
    }
  }
}
整数(Integer)

整数(Integer):整数类型用于存储整数值,如年龄、分数等。Elasticsearch支持的有符号整数类型包括:

  1. byte:8位有符号整数,范围是-128到127。
  2. short:16位有符号整数,范围是-32768到32767。
  3. integer:32位有符号整数,范围是-2147483648到2147483647。
  4. long:64位有符号整数,范围是-9223372036854775808到9223372036854775807。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      }
    }
  }
}
浮点数(Floating point)

浮点数(Floating point):浮点数类型用于存储小数值,如价格、重量等。Elasticsearch支持的浮点数类型包括:

  1. float:32位浮点数,精度较低,适合存储较大的数值范围。
  2. double:64位浮点数,精度较高,适合存储较小的数值范围。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "price": {
        "type": "double"
      }
    }
  }
}
日期(Date)

日期(Date):日期类型用于存储日期和时间信息。Elasticsearch支持多种日期格式,包括ISO 8601格式和其他自定义格式。日期类型还可以存储时间戳,表示从1970年1月1日00:00:00 UTC到当前时间的毫秒数。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "birthday": {
        "type": "date",
        "format": "strict_date_optional_time||epoch_millis"
      }
    }
  }
}

# 写入数据
POST /my_index/_doc/1
{
  "date": "2023-04-05T14:12:12Z"
}

POST /my_index/_doc/2
{
  "date": 1649168857000
}

date 字段指定了两个格式:

  • strict_date_optional_time:这是一个内置的格式,它支持类似 2023-04-05T14:12:12Z 的 ISO 8601 兼容日期。
  • epoch_millis:代表从 Unix epoch (1970年1月1日 UTC) 开始的毫秒数,例如 1649168857000
    查询日期

对日期字段进行查询时,你也可以使用多种格式来指定日期值。

GET /my_index/_search
{
  "query": {
    "range": {
      "date": {
        "gte": "2023-04-05T00:00:00Z",
        "lte": "now"
      }
    }
  }
}

在上面的查询中,我们使用 range 查询来寻找日期在 2023-04-05T00:00:00Z 到当前时间之间的文档。

自定义日期格式
可以指定自定义的日期格式,使用 Java 的 SimpleDateFormat 风格的日期格式:

PUT /my_custom_index
{
  "mappings": {
    "properties": {
      "custom_date": { 
        "type":   "date",
        "format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"
      }
    }
  }
}

POST /my_custom_index/_doc/1
{
  "custom_date": "2023/04/05 14:12:12"
}

POST /my_custom_index/_doc/2
{
  "custom_date": "2023/04/05"
}

这个自定义格式接受两种日期格式:完整的日期时间和只有日期的字符串。当然,Elasticsearch 还支持其他更多的内置格式和自定义格式,你可以根据你的需求来指定。

布尔值(Boolean)

布尔值(Boolean):布尔值类型用于存储真/假值,如是否可用、是否已读等。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "is_active": {
        "type": "boolean"
      }
    }
  }
}
二进制(Binary)

二进制(Binary):二进制类型用于存储二进制数据,如图片、音频、视频等。

建立mappings例子:

PUT /my_index
{
  "mappings": {
    "properties": {
      "photo": {
        "type": "binary"
      }
    }
  }
}
嵌套对象

在Elasticsearch中,嵌套对象是一种复杂的数据类型,它允许你将一个对象嵌入到另一个对象中。这种数据类型非常适合用于表示具有层次结构的关系数据,例如订单中的商品,或者用户中的地址。

object和nested类型的区别:

  1. Object类型:Object类型用于存储嵌套的对象或文档。当您查询一个object字段时,Elasticsearch会将整个嵌套对象作为一个整体进行处理。这意味着,如果您想要查询嵌套对象内部的某个字段,您需要将整个嵌套对象都包含在查询中。此外,object类型不支持对嵌套对象内部的多个实例进行独立的查询。
  2. Nested类型:Nested类型是object类型的特殊版本,它允许对象数组以一种可以相互独立查询的方式进行索引。在Nested内部,每个对象索引其实是一个单独的隐藏文档,这意味着每个嵌套对象都可以独立于其他对象进行查询。这使得Nested类型在处理复杂的查询场景时更加灵活和强大。

总的来说,object类型更适合处理简单的嵌套文档,而nested类型更适合处理复杂的嵌套文档和查询场景。

假设我们有一个订单(Order)对象,每个订单包含一个客户(Customer)对象和一个商品(Product)对象的列表。我们可以这样定义映射:

PUT /orders
{
  "mappings": {
    "properties": {
      "customer": {
        "type": "object"
      },
      "products": {
        "type": "nested"
      }
    }
  }
}

# 向索引中插入一个文档
POST /orders/_doc
{
  "customer": {
    "name": "John Doe",
    "email": "john.doe@example.com"
  },
  "products": [
    {
      "name": "Product A",
      "price": 100
    },
    {
      "name": "Product B",
      "price": 200
    }
  ]
}

# 查询所有包含"Product A"的订单
GET /orders/_search
{
  "query": {
    "nested": {
      "path": "products",
      "query": {
        "match": {
          "products.name": "Product A"
        }
      }
    }
  }
}

"customer"字段是一个普通对象,而"products"字段是一个嵌套对象。这意味着"products"字段中的每个元素都可以单独进行查询和过滤。

地理空间

在Elasticsearch中,地理空间搜索是一种基于地理位置的搜索功能,它可以让你根据文档的位置信息进行搜索。Elasticsearch支持多种地理空间数据类型,包括地理坐标(geo_point)和多边形(geo_shape)。

建立mappings例子:

PUT /users
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

# 插入一个文档
POST /users/_doc
{
  "name": "John Doe",
  "location": {
    "lat": 40.7128,
    "lon": -74.0060
  }
}

# 查询距离某个地点一定范围内的所有用户
GET /users/_search
{
  "query": {
    "geo_distance": {
      "distance": "100km",
      "location": {
        "lat": 40.7128,
        "lon": -74.0060
      }
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲上云霄的Jayden

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值