elasticsearch篇之mapping

2018年05月17日 18:01:37 lyzkks 阅读数:444更多

个人分类: Elastic stack

版权声明:文章内容来自于网络和博主自身学习体会,转载请注明出处,欢迎留言大家一起讨论学习~~ https://blog.csdn.net/sinat_35930259/article/details/80354732

什么是mapping



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

  • 定义index下的字段名
  • 定义字段类型,比如数值型、浮点型、布尔型等
  • 定义倒排索引相关的设置,比如是否索引、记录position等

查看mapping


GET /[index_name]/_mapping
  • 1

其中 keyword表示部分次的字符串类型

自定义mapping


api

说明

mapping中的字段类型一旦设置,禁止直接修改,因为 lucene实现的倒排索引生成后不允许修改,应该重新建立新的索引,然后做reindex操作。

但是可以新增字段,通过 dynamic 参数来控制字段的新增,这个参数的值如下:

  • true:默认值,表示允许选自动新增字段
  • false:不允许自动新增字段,但是文档可以正常写入,但无法对字段进行查询等操作
  • strict:严格模式,文档不能写入,报错 

示例

首先创建名为 my_index的索引并设置mapping:

PUT my_index
{
  "mappings": {
    "doc": {
      "dynamic": false,
      "properties": {
        "title": {
          "type": "text"
        },
        "name": {
          "type": "keyword"
        },
        "age": {
          "type": "integer"
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

其中包含了 title、name、age三个字段

查询索引的mapping设置:

GET my_index/_mapping
  • 1

然后写入一个文档:

PUT my_index/doc/1
{
  "title": "hello world",
  "desc": "this is book"
}
  • 1
  • 2
  • 3
  • 4
  • 5

注意,这里在mapping设置中,”dynamic”: false,表示在写入文档时,如果写入字段不存在也不会报错。这里的desc字段就是不存在的字段。

查询一下写入的文档:

GET my_index/doc/_search
{
  "query": {
    "match": {
      "title": "hello"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以通过 title字段查询到文档的内容

如果说想通过desc字段查询文档内容呢?当然是查不到的:

GET my_index/doc/_search
{
  "query": {
    "match": {
      "desc": "book"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以验证一下”dynamic”: strict模式: 
首先删除索引:

DELETE my_index
  • 1

然后修改索引mapping设置:

PUT my_index
{
  "mappings": {
    "doc": {
      "dynamic": "strict",
      "properties": {
        "title": {
          "type": "text"
        },
        "name": {
          "type": "keyword"
        },
        "age": {
          "type": "integer"
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在重新创建文档:

PUT my_index/doc/1
{
  "title": "hello world",
  "desc": "this is book"
}
  • 1
  • 2
  • 3
  • 4
  • 5

在strict 模式下插入不存在的字段将会出现报错

copy_to参数说明

作用是将该字段的值复制到目标字段,实现类似_all的作用。不会出现在_source中,只能用来搜索。

PUT my_index4
{
  "mappings": {
    "doc": {
      "properties": {
        "first_name": {
          "type": "text"
          , "copy_to": "full_name"
        },
        "last_name": {
          "type": "text"
          , "copy_to": "full_name"
        },
        "full_name" : {
          "type": "text"
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

可以看到这个index中,full_name的内容就是从 first_name 和 last_name 中复制过来的。

然后创建一个新的文档,文档只需要写first_name 和 last_name即可:

PUT my_index4/doc/1
{
  "first_name": "john",
  "last_name": "smith"
}
  • 1
  • 2
  • 3
  • 4
  • 5

最后查询一下文档的内容:

GET my_index4/_search
{
  "query": {
    "match": {
      "full_name": {
        "query": "john smith",
        "operator": "and"
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这个查询语句意思是:查询包含关键字john smith的文档,必须同时包含两个关键字才返回。

index参数

index参数作用是控制当前字段是否被索引,默认为true,false表示不记录,即不可被搜索。

PUT my_index5
{
  "mappings": {
    "doc": {
      "properties": {
        "cookie": {
          "type": "text",
          "index": false
        },
        "content": {
          "type": "text",
          "index": true
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这个index有两个字段,其中cookie设定为不可被搜索

写入文档:

PUT my_index5/doc/1
{
  "cookie": "name=mike",
  "content": "hello world"
}
  • 1
  • 2
  • 3
  • 4
  • 5

尝试分别查询一下两个字段,看看区别:

GET my_index5/_search
{
  "query": {
    "match": {
      "cookie": "mike"
    }
  }
}

GET my_index5/_search
{
  "query": {
    "match": {
      "content": "hello"
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

当在es中存储了一些不想要被检索的字段如身份证、手机等,这是对于这些字段就可以使用index设置为false,这样有一定的安全性还可以节省空间

index_options参数

index_options的作用是用于控制倒排索引记录的内容,有如下四种配置:

  • docs:只记录doc id
  • freqs:记录doc id 和term frequencies
  • positions:记录doc id、 term frequencies和term position
  • offsets:记录doc id、 term frequencies、term position、character offsets

text类型的默认配置为positions,其他默认为docs。记录的内容越多,占据的空间越大。

null_value参数

这个参数的作用是当字段遇到null值的时候的处理策略,默认为null,即空值,此时es会忽略该值。可以通过这个参数设置某个字段的默认值。

数据类型


核心数据类型

  • 字符串型:text、keyword(不会分词)
  • 数值型:long、integer、short、byte、double、float、half_float等
  • 日期类型:date
  • 布尔类型:boolean
  • 二进制类型:binary
  • 范围类型:integer_range、float_range、long_range、double_range、date_range

复杂数据类型

  • 数组类型:array
  • 对象类型:object
  • 嵌套类型:nested object
  • 地理位置数据类型:geo_point、geo_shape
  • 专用类型:ip(记录ip地址)、completion(实现自动补全)、token_count(记录分词数)、murmur3(记录字符串hash值)

多字段特性

多字段特性(multi-fields),表示允许对同一字段采用不同的配置,比如分词。

常见例子是对人名实现拼音搜索,只需要在人名中新增一个字段pinyin即可。但是这种方式不是十分优雅,multi-fields可以在不改变整体结构的前提下,增加一个子字段: 

Dynamic mapping


自动识别规则

在前面说过,在写入文档的时候如果index不存在的话es会自动创建这个索引。但是es是如何确定index字段的类型的呢?

首先es可以自动识别文档字段的类型,这样可以降低用户的使用成本。 

es是依靠json文档的字段类型来实现自动识别字段类型的: 

日期自动识别

日期的自动识别可以自行配置日期的格式,默认情况下是:

["strict_date_opeional_time", "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
  • 1

strict_date_opeional_time 是ISO 标准的日期格式,完整的格式如下:

YYYY-MM-DDhh:mm:ssTZD(eg:1997-07-16y19:20:30+01:00)
  • 1

dynamic_date_formats:可以自定义日期类型 
date_detection:可以关闭日期自动识别机制(默认开启)

首先创建一个日期自动识别的索引:

PUT test_index
{
  "mappings": {
    "doc": {
      "dynamic_date_formats": ["MM/dd/yyyy"]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后创建一个文档:

PUT test_index/doc/1
{
  "create_time": "09/21/2016"
}
  • 1
  • 2
  • 3
  • 4

查看:

GET test_index/_mapping
  • 1

关闭日期自动识别可以如下: 

数字自动识别

字符串为数字的时候,默认不会自动识别为整型,因为字符串中出现数字是完全合理的。

numeric_detection 可以开启字符串中数字的自动识别。 

Dynamic Templates



Dynamic Templates 意为 动态模板,它的作用是允许根据es自动识别的数据类型、字段名等来动态设定字段类型。

可以实现的效果如下:

  • 所有字符串类型都设置为keyword类型,即默认不分词
  • 所有以message开头的字段都设置为text类型,即分词
  • 所有以long_开头的字段都设置为long类型
  • 所有自动匹配为double类型的都设定为float类型,以节省空间

API

匹配规则参数

  • match_mapping_type:匹配es自动识别的字段类型,如boolean、long等
  • match、unmatch:匹配字段名
  • path_match、path_unmatch:匹配路径

举例

字段类型匹配

首先PUT一个文档,然后查看mapping:

PUT test_index/doc/1
{
  "name": "Tom"
}

GET test_index/_mapping
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到在默认情况下,字符串被识别成为text类型,并且有一个子字段keyword。

现在设置动态模板,要求匹配到string类型的字段设置为keyword:

PUT test_index
{
  "mappings": {
    "doc": {
      "dynamic_templates": [
        {
          "strings_as_keywords": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ]
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

重新创建文档并查看mapping: 

name字段的类型变成了 keyword类型

字段匹配

现在想将以message开头的字段且为string的匹配称为text类型,其余为keyword:

PUT test_index
{
  "mappings": {
    "doc": {
      "dynamic_templates": [
        {
          "message_as_text": {
            "match_mapping_type": "string",
            "match": "message",
            "mapping": {
              "type": "text"
            }
          }
        },
        {
          "strings_as_keywords": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Dynamic Templates 的匹配顺序是从上到下执行的,匹配到一个后后面的规则就会跳过

然后创建一个文档并查看mapping:

PUT test_index/doc/1
{
  "name": "john",
  "message": "good boy"
}

GET test_index/_mapping
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看到message被设置为了text类型,name还是keyword

double设定为float

这样可以节省空间

自定义mapping的建议


一般步骤

自定义mapping 的步骤:

  1. 写一条文档到es的临时索引中,获取es自动生成的mapping
  2. 修改第一步得到的mapping,自定义相关配置
  3. 使用第2步的mapping创建市级的索引

实际举例

假设我得到了需要存入es的文档,首先将文档写入临时的index中:

PUT test_index/doc/1
{
  "referre": "-",
  "response_code": "200",
  "remote_ip": "172.0.0.1",
  "method": "POST",
  "username": "-",
  "http_version": "1.1",
  "body_sent": {
    "bytes": "0"
  },
  "url": "/helloworld"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

然后查看es自动生成的mapping:

GET test_index/_mapping
  • 1

现在希望将bytes设置为整型,url设置为text类型,其他都使用keyword(将上一步的输出复制过来就好):

PUT product_index
{
    "mappings": {
      "doc": {
        "properties": {
          "body_sent": {
            "properties": {
              "bytes": {
                "type": "long"
              }
            }
          },
          "http_version": {
            "type": "keyword"
          },
          "method": {
            "type": "keyword"
          },
          "referre": {
            "type": "keyword"
          },
          "remote_ip": {
            "type": "keyword"
          },
          "response_code": {
            "type": "keyword"
          },
          "url": {
            "type": "text"
          },
          "username": {
            "type": "keyword"
          }
        }
      }
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

这样直接将测试index的mapping复制过来进行修改,不会遗漏字段,修改完成设置一个index的名称就行了。

然后就可以向实际的索引中写入文档了:

PUT product_index/doc/1
{
  "referre": "-",
  "response_code": "200",
  "remote_ip": "172.0.0.1",
  "method": "POST",
  "username": "-",
  "http_version": "1.1",
  "body_sent": {
    "bytes": "0"
  },
  "url": "/helloworld"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

然后查看一下实际索引的mapping:

GET product_index/_mapping
  • 1

使用动态模板优化

上边的设置方法很直接,但是当字段比较多的时候显得复杂,可以使用动态模板进行匹配:

DELETE product_index

PUT product_index
{
    "mappings": {
      "doc": {
        "dynamic_templates": [
          {
            "strings": {
              "match_mapping_type": "string",
              "mapping": {
                "type": "keyword"
              }
            }
          }
        ],
        "properties": {
          "body_sent": {
            "properties": {
              "bytes": {
                "type": "long"
              }
            }
          },
          "url": {
            "type": "text"
          },
          "username": {
            "type": "keyword"
          }
        }
      }
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

这里使用动态模板匹配所有字符串都设置为keyword类型,需要单独设置类型的在下面另行指出。

索引模板

什么是索引模板

索引模板,index template,主要用于在新建索引时自动应用预先设置的配置,简化索引创建的步骤。

模板中可以设定索引的配置以及mapping,可以有多个模板,根据order设置,order大的覆盖小的范围。

API

模板加载顺序根据 order 从小到大加载,后面的大order的模板的配置将会覆盖小 order配置。

获取与删除的API 如下: 

举例

这里设置了两个索引模板:

PUT _template/test_template
{
  "index_patterns": ["te*", "bar*"],
  "order": 0,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc": {
      "_source": {
        "enabled": false
      },
      "properties": {
        "name": {
          "type": "keyword"
        }
      }
    }
  }
}

PUT _template/test_template2
{
  "index_patterns": ["test*"],
  "order": 1,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc": {
      "_source": {
        "enabled": true
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

然后先创建一个foo_index,并获取一下它的mapping:

PUT foo_index
GET foo_index/_mapping
  • 1
  • 2

因为这个index没有被任何一个模板匹配到,所以它的mapping是空的

再创建一个bar_index,并获取一下它的mapping:

PUT bar_index
GET bar_index/_mapping
  • 1
  • 2

这个索引匹配到了test_template

再创建一个test_index,并获取一下它的index配置:

PUT test_index
GET test_index/
  • 1
  • 2

这个索引匹配到了test_template2模板,这使得索引的”_source”: {“enabled”: true}

原文地址:https://www.cnblogs.com/bigben0123/p/10057121.html

时间: 2024-08-23 23:06:25

elasticsearch篇之mapping的相关文章

Elasticsearch系列---定制mapping

概要 本篇接着前一篇内容,继续介绍mapping信息,重点倾向于自定义mapping.自定义对象以及数组集合类的底层结构. 自定义mapping 上一篇文章介绍的都是Elasticsearch的自动mapping,我们在创建索引时,可以先指定好mapping的信息,还是以music索引为例: PUT /music { "mappings": { "children": { "properties": { "content":

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字段的类型以及相关属性elasticsearch会根据json源数据的基础类型猜测你想要的字段映射,将输入的数据转换成可搜索的索引项,mapping就是我们自己定义的字段数据类型,同时告诉elasticsearch如何索引数据以及是否可以被搜索 作用:会让索引建立的更加细致和完善 类型:静态映射和动态

elasticsearch中的mapping映射配置与查询典型案例

elasticsearch中的mapping映射配置示例比如要搭建个中文新闻信息的搜索引擎,新闻有"标题"."内容"."作者"."类型"."发布时间"这五个字段:我们要提供"标题和内容的检索"."排序"."高亮"."统计"."过滤"等一些基本功能.ES提供了smartcn的中文分词插件,测试的话建议使用IK分

Elasticsearch:Dynamic mapping

Elasticsearch最重要的功能之一是它试图摆脱你的方式,让你尽快开始探索你的数据. 要索引文档,您不必首先创建索引,定义映射类型和定义字段 - 您只需索引文档,那么index,type和field将自动生效.比如: PUT data/_doc/1 { "count": 5 } 上面的命令将自动帮我们生成一个叫做data的index,并同时生成一个叫做_doc的type及一个叫做count的field.count的数据类型是long.这个非常方便,我们不想传统的RDMS那样,先要

Elasticsearch系列---初识mapping

概要 本篇简单介绍一下field数据类型mapping的相关知识. mapping是什么? 前面几篇的实战案例,我们向Elasticsearch索引数据时,只是简单地把JSON文本放在请求体里,至于JSON里的field类型,存储到ES里是什么类型,中间是怎么做的映射,这个映射过程,就是mapping要解决的问题. mapping简单来说,就是解决JSON文本内容到field类型映射关系的定义.将时间域视为时间类型,数字视为数字类型,字符串识别为全文或精确值字符串,这个识别的过程,叫做mappi

Elasticsearch如何修改Mapping结构并实现业务零停机

Elasticsearch 版本:6.4.0 一.疑问 在项目中后期,如果想调整索引的 Mapping 结构,比如将 ik_smart 修改为 ik_max_word 或者 增加分片数量 等,但 Elasticsearch 不允许这样修改呀,怎么办? 常规 解决方法: 根据最新的 Mapping 结构再创建一个索引 将旧索引的数据全量导入到新索引中 告知用户,业务要暂停使用一段时间 修改程序,将索引名替换成新的索引名称,打包,重新上线 告知用户,服务可以继续使用了,并说一声抱歉 我认为最大的弊端

ElasticSearch Index API && Mapping

ElasticSearch  NEST Client 操作Index var indexName="twitter"; var deleteIndexResponse = client.DeleteIndex(indexName);                var createIndexResponse = client.CreateIndex(indexName);                var getIndexResponse = client.GetIndex(in

ElasticSearch 基础(4) - Mapping

一.Mapping概述 为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成Full-text或者精确的字符串值. ES需要知道每个字段里面都包含了什么类型.这些类型和字段的信息存储(包含)在映射(mapping)中. 索引中每个文档都有一个类型(type).每个类型都拥有自己的映射(mapping)或者模式定义(schema definition). 一个映射定义了字段类型,每个字段的数据类型,以及字段被Elasticsearch处理的方式.映射还用于设置关联到类型上的元数据

elasticsearch index 之 Mapping

Lucene索引的一个特点就filed,索引以field组合.这一特点为索引和搜索提供了很大的灵活性.elasticsearch则在Lucene的基础上更近一步,它可以是 no scheme.实现这一功能的秘密就Mapping.Mapping是对索引各个字段的一种预设,包括索引与分词方式,是否存储等,数据根据字段名在Mapping中找到对应的配置,建立索引.这里将对Mapping的实现结构简单分析,Mapping的放置.更新.应用会在后面的索引fenx中进行说明. 首先看一下Mapping的实现