elasticsearch之mappings是什么鬼東西


前言

我們已經自由奔放夠了!

我們應該知道,在關系型數據庫中,必須先定義表結構,才能插入數據,並且,表結構不會輕易改變。而我們呢,我們怎么玩elasticsearch的呢:

PUT t1/doc/1
{
  "name": "小黑"
}
PUT t1/doc/2
{
  "name": "小白",
  "age": 18
}

文檔的字段可以是任意的,原本都是name字段,突然來個age。還要elasticsearch自動去猜,哦,可能是個long類型,然后加個映射!之后發什么什么?肯定是:猜猜猜,猜你妹!
難道你不想知道elasticsearch內部是怎么玩的嗎?
當我們執行上述第一條PUT命令后,elasticsearch到底是怎么做的:

GET t1

結果:

{
  "t1" : {
    "aliases" : { },
    "mappings" : {
      "doc" : {
        "properties" : {
          "name" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1553334893136",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "lHfujZBbRA2K7QDdsX4_wA",
        "version" : {
          "created" : "6050499"
        },
        "provided_name" : "t1"
      }
    }
  }
}

由返回結果可以看到,分為兩大部分,第一部分關於t1索引類型相關的,包括該索引是否有別名aliases,然后就是mappings信息,包括索引類型doc,各字段的詳細映射關系都收集在properties中。
另一部分是關於索引t1settings設置。包括該索引的創建時間,主副分片的信息,UUID等等。
我們再執行第二條PUT命令,再查看該索引是否有什么變化,返回結果如下:

{
  "t1" : {
    "aliases" : { },
    "mappings" : {
      "doc" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1553334893136",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "lHfujZBbRA2K7QDdsX4_wA",
        "version" : {
          "created" : "6050499"
        },
        "provided_name" : "t1"
      }
    }
  }
}

由返回結果可以看到,settings沒有變化,只是mappings中多了一條關於age的映射關系,這一切都是elasticsearch自動的,但特定的場景下,需要我們更多的設置。
所以,接下來,我們研究一下mappings這個小老弟,到底是怎么回事!

映射是什么?

其實,映射mappings沒那么神秘!說白了,就相當於原來由elasticsearch自動幫我們定義表結構。現在,我們要自己來了,旨在創建索引的時候,有更多定制的內容,更加的貼合業務場景。OK,坐好了,開車!
elasticsearch中的映射用來定義一個文檔及其包含的字段如何存儲和索引的過程。例如,我們可以使用映射來定義:

  • 哪些字符串應該被視為全文字段。
  • 哪些字段包含數字、日期或者地理位置。
  • 定義日期的格式。
  • 自定義的規則,用來控制動態添加字段的的映射。

身為吃瓜群眾的小老弟,不懂沒關系,往下走!

映射類型

每個索引都有一個映射類型(這話必須放在elasticsearch6.x版本后才能說,之前版本一個索引下有多個類型),它決定了文檔將如何被索引。

映射類型有:

  • 元字段(meta-fields):元字段用於自定義如何處理文檔關聯的元數據,例如包括文檔的_index_type_id_source字段。
  • 字段或屬性(field or properties):映射類型包含與文檔相關的字段或者屬性的列表。

還不懂,沒關系,繼續往下走!

字段的數據類型

  • 簡單類型,如文本(text)、關鍵字(keyword)、日期(date)、整形(long)、雙精度(double)、布爾(boolean)或ip
  • 可以是支持JSON的層次結構性質的類型,如對象或嵌套。
  • 或者一種特殊類型,如geo_pointgeo_shapecompletion

為了不同的目的,以不同的方式索引相同的字段通常是有用的。例如,字符串字段可以作為全文搜索的文本字段進行索引,也可以作為排序或聚合的關鍵字字段進行索引。或者,可以使用標准分析器、英語分析器和法語分析器索引字符串字段。

這就是多字段的目的。大多數數據類型通過fields參數支持多字段。

映射約束

在索引中定義太多的字段有可能導致映射爆炸!因為這可能會導致內存不足以及難以恢復的情況,為此。我們可以手動或動態的創建字段映射的數量:

  • index.mapping.total_fields.limit:索引中的最大字段數。字段和對象映射以及字段別名都計入此限制。默認值為1000。
  • index.mapping.depth.limit:字段的最大深度,以內部對象的數量來衡量。例如,如果所有字段都在根對象級別定義,則深度為1.如果有一個子對象映射,則深度為2,等等。默認值為20。
  • index.mapping.nested_fields.limit:索引中嵌套字段的最大數量,默認為50.索引1個包含100個嵌套字段的文檔實際上索引101個文檔,因為每個嵌套文檔都被索引為單獨的隱藏文檔。

一個簡單的映射示例

PUT mapping_test1
{
  "mappings": {
    "test1":{
      "properties":{
        "name":{"type": "text"},
        "age":{"type":"long"}
      }
    }
  }
}

上例中,我們在創建索引PUT mapping_test1的過程中,為該索引定制化類型(設計表結構),添加一個映射類型test1;指定字段或者屬性都在properties內完成。

GET mapping_test1

通過GET來查看。

{
  "mapping_test1" : {
    "aliases" : { },
    "mappings" : {
      "test1" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1550469220778",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "7I_m_ULRRXGzWcvhIZoxnQ",
        "version" : {
          "created" : "6050499"
        },
        "provided_name" : "mapping_test1"
      }
    }
  }
}

返回的結果中你肯定很熟悉!映射類型是test1,具體的屬性都被封裝在properties中。而關於settings的配置,我們暫時不管它。

我們為這個索引添加一些數據:

put mapping_test1/test1/1
{
  "name":"張開嘴",
  "age":16
}

上例中,mapping_test1是之前創建的索引,test1為之前自定義的mappings類型。字段是之前創建好的nameage

GET mapping_test1/test1/_search
{
  "query": {
    "match": {
      "age": 16
    }
  }
}

上例中,我們通過age條件查詢。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "mapping_test1",
        "_type" : "test1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "張開嘴",
          "age" : 16
        }
      }
    ]
  }
}

返回了預期的結果信息。


歡迎斧正,that's all


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM