ElasticSearch 学习笔记 - 6. 映射Mapping

一、概述

映射(Mapping)至关于数据表的表结构。
ElasticSearch中的映射(Mapping)用来定义一个文档,能够定义所包含的字段以及字段的类型、分词器及属性等等。数据库

映射能够分为动态映射和静态映射。
(1)动态映射
咱们知道,在关系数据库中,须要事先建立数据库,而后在该数据库实例下建立数据表,而后才能在该数据表中插入数据。
而ElasticSearch中不须要事先定义映射(Mapping),文档写入ElasticSearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。数组

(2)静态映射
固然,在ElasticSearch中也能够事先定义好映射,包含文档的各个字段及其类型等,这种方式称之为静态映射。app

二、动态映射实例

(1)新建索引oop

PUT /book

(2)查看空索引设计

GET /book/_mapping

{
  "book": {
    "mappings": {}
  }
}

(3)插入文档code

PUT book/it/1
{
  "bookId":1,
  "bookName":"Java程序设计",
  "publishDate":"2018-01-12"
}

{
  "_index": "book",
  "_type": "it",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}

(4)再次查看映射对象

GET /book/_mapping

{
  "book": {
    "mappings": {
      "it": {
        "properties": {
          "bookId": {
            "type": "long"
          },
          "bookName": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "publishDate": {
            "type": "date"
          }
        }
      }
    }
  }
}

bookId字段推测为long型,
bookName字段推测为text类型,
publishDate字段推测为date类型,
这些推测都是咱们能够接受的。可见ElasticSearch的动态映射十分强大。索引

三、动态映射规则

JSON数据 自动推测的类型
null 没有字段被添加
true或false boolean型
小数 float型
数字 long型
日期 date或text
字符串 text
数组 由数组第一个非空值决定
JSON对象 object类型

四、静态映射

动态映射的自动类型推测功能并非100%正确的,这就须要静态映射机制。
静态映射与关系数据库中建立表语句类型,须要事先指定字段类型。相对于动态映射,静态映射能够添加更加详细字段类型、更精准的配置信息等。文档

(1)新建映射字符串

PUT books
{
  "mappings":{
    "it": {
       "properties": {
          "bookId": {"type": "long"},
          "bookName": {"type": "text"},
          "publishDate": {"type": "date"}
       }
    }
  }
}

(2)查看映射

GET /books/_mapping

{
  "books": {
    "mappings": {
      "it": {
        "properties": {
          "bookId": {
            "type": "long"
          },
          "bookName": {
            "type": "text"
          },
          "publishDate": {
            "type": "date"
          }
        }
      }
    }
  }
}

(3)插入数据

PUT books/it/1
{
  "bookId":"1",
  "bookName":"Java",
  "publishDate":"2018-01-12"

}

(4)查询

GET books/it/1

{
  "_index": "books",
  "_type": "it",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "bookId": "1",
    "bookName": "Java",
    "publishDate": "2018-01-12"
  }
}

五、静态+动态

(1)加入不在静态映射的字段

PUT books/it/2
{
  "bookId":"2",
  "bookName":"Hadoop",
  "author":"chengyuqiang",
  "publishDate":"2018-01-13"

}

(2)查看索引

GET books/_mapping

{
  "books": {
    "mappings": {
      "it": {
        "properties": {
          "author": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "bookId": {
            "type": "long"
          },
          "bookName": {
            "type": "text"
          },
          "publishDate": {
            "type": "date"
          }
        }
      }
    }
  }
}

经过自动映射添加了新的不存在的字段 author

六、type设计失误

为何映射类型被删除?

ES的索引相似于关系型数据库中的数据库,
一个映射类型则至关于关系型数据库中的一张表。

这是一个错误的类比,致使了错误的假设。
在一个关系型数据库中,表之间是相互独立的。
一个表中的列与另外一个表中同名的列没有关系。然而在映射类型中却不是这样的。

在一个Elasticsearch的索引中,有相同名称字段的不一样映射类型在Lucene内部是由同一个字段支持的。

换言之,看下面的这个例子,user 类型中的 user_name字段和tweet类型中的user_name字段其实是被存储在同一个字段中,并且两个user_name字段在这两种映射类型中都有相同的定义(如类型都是 text或者都是date)。

这会致使一些问题,好比,当你但愿在一个索引中的两个映射类型,一个映射类型中的 deleted 字段映射为一个日期数据类型的字段,而在另外一个映射类型中的deleted字段映射为一个布尔数据类型的字段,这就会失败。

最重要的是,在一个索引中存储那些有不多或没有相同字段的实体会致使稀疏数据,而且干扰Lucene有效压缩文档的能力。

相关文章
相关标签/搜索