【Elasticsearch】Elasticsearch 核心技術(二):映射

Elasticsearch 核心技術(二):映射

  • 1.什么是映射(Mapping)
    • 1.1 元字段(Meta-Fields)
    • 1.2 數據類型 vs 映射類型
      • 1.2.1 數據類型
      • 1.2.2 映射類型
  • 2.實際運用案例
    • 案例 1:電商產品索引映射
    • 案例 2:動態模板設置
  • 3.動態映射與靜態映射詳解
    • 3.1 動態映射 (Dynamic Mapping)
      • 3.1.1 動態映射的三種模式
      • 3.1.2 動態映射示例
    • 3.2 靜態映射(Explicit Mapping)
      • 靜態映射示例
    • 3.3 對比
    • 3.4 最佳實踐建議
  • 4.映射修改詳解
    • 4.1 可以修改的內容
    • 4.2 不可修改的內容
    • 4.3 修改映射的解決方案
    • 4.4 案例:將字符串字段從 text 改為 keyword
      • 4.4.1 錯誤方式(直接修改會失敗)
      • 4.4.2 正確方式(通過重建索引)
    • 4.5 注意事項
  • 5.注意事項

1.什么是映射(Mapping)

映射是 Elasticsearch 中定義文檔及其包含字段如何存儲和索引的過程。它相當于關系型數據庫中的表結構定義,決定了:

  • 每個字段的數據類型
  • 字段是否被索引
  • 字段的索引方式
  • 字段的分析器設置
  • 字段的格式(如日期格式)

1.1 元字段(Meta-Fields)

元字段是 Elasticsearch 為每個文檔自動創建的內部字段,用于管理文檔的元數據。常見的元字段包括:

  • 標識元字段
    • _index:文檔所屬的索引
    • _id:文檔的唯一 ID
  • 文檔源元字段
    • _source:存儲原始 JSON 文檔
  • 索引元字段
    • _field_names:包含非空值的所有字段
  • 路由元字段
    • _routing:用于將給定文檔路由到指定的分片。
  • 其他元字段
    • _meta:應用特定的元數據
    • _version:文檔版本號

例如 Kibana 中自帶的 sample_data_ecommerce 示例數據。

在這里插入圖片描述

下面框出來的就是元字段信息。

在這里插入圖片描述

1.2 數據類型 vs 映射類型

1.2.1 數據類型

指字段值的具體類型,如:

  • 核心類型:textkeywordlongintegershortbytedoublefloatbooleandate
  • 復雜類型:objectnested
  • 地理類型:geo_pointgeo_shape
  • 特殊類型:ipcompletiontoken_count

1.2.2 映射類型

在 Elasticsearch 7.0 之前,索引可以包含多個類型(類似于表),但 7.0 之后已棄用,每個索引現在只有一個隱式的 _doc 類型。

2.實際運用案例

案例 1:電商產品索引映射

PUT /products
{"mappings": {"properties": {"name": { "type": "text", "analyzer": "ik_max_word" },"price": { "type": "double" },"description": { "type": "text" },"category": { "type": "keyword" },"tags": { "type": "keyword" },"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" },"specs": { "type": "object" },"location": { "type": "geo_point" }}}
}

案例 2:動態模板設置

PUT /my_index
{"mappings": {"dynamic_templates": [{"strings_as_keywords": {"match_mapping_type": "string","mapping": {"type": "keyword"}}}]}
}

3.動態映射與靜態映射詳解

3.1 動態映射 (Dynamic Mapping)

動態映射是 Elasticsearch 自動檢測和創建字段映射的能力。當索引一個新文檔時,如果包含未定義的字段,Elasticsearch 會根據字段值自動推斷數據類型并創建映射。

3.1.1 動態映射的三種模式

  • true(默認):自動添加新字段
  • false:忽略新字段(不索引但會存儲在 _source 中)
  • strict:拒絕包含新字段的文檔(拋出異常)

3.1.2 動態映射示例

# 創建索引時不定義映射(使用默認動態映射)
PUT /dynamic_index# 插入包含新字段的文檔
POST /dynamic_index/_doc/1
{"name": "John Doe",  # 自動識別為text字段"age": 30,          # 自動識別為long"birth_date": "1990-01-01",  # 自動識別為date"is_active": true,   # 自動識別為boolean"salary": 5000.50,   # 自動識別為float"tags": ["tech", "sports"],  # 自動識別為text數組"address": {         # 自動識別為object"street": "123 Main St","city": "New York"}
}

查看自動生成的映射

GET /dynamic_index/_mapping# 返回結果示例:
{"dynamic_index": {"mappings": {"properties": {"address": {"properties": {"city": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },"street": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }}},"age": { "type": "long" },"birth_date": { "type": "date" },"is_active": { "type": "boolean" },"name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },"salary": { "type": "float" },"tags": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }}}}
}

3.2 靜態映射(Explicit Mapping)

靜態映射是手動預定義索引的字段結構和數據類型,在創建索引時明確指定每個字段的類型和屬性。

靜態映射示例

# 創建索引時明確定義映射
PUT /static_index
{"mappings": {"dynamic": "strict",  # 嚴格模式,禁止未定義的字段"properties": {"name": {"type": "text","analyzer": "standard","fields": {"keyword": { "type": "keyword" }}},"age": { "type": "integer" },"birth_date": {"type": "date","format": "yyyy-MM-dd||epoch_millis"},"is_active": { "type": "boolean" },"salary": { "type": "scaled_float", "scaling_factor": 100 },"tags": {"type": "keyword"},"address": {"type": "object","properties": {"street": { "type": "keyword" },"city": { "type": "keyword" },"coordinates": { "type": "geo_point" }}},"comments": {"type": "nested","properties": {"user": { "type": "keyword" },"message": { "type": "text" },"rating": { "type": "byte" }}}}}
}

嘗試插入未定義字段的文檔

POST /static_index/_doc/1
{"name": "Jane Smith","age": 28,"new_field": "test"  # 將拋出異常,因為dynamic=strict
}# 錯誤響應:
{"error": {"root_cause": [{"type": "strict_dynamic_mapping_exception","reason": "mapping set to strict, dynamic introduction of [new_field] within [_doc] is not allowed"}]},"status": 400
}

3.3 對比

特性動態映射靜態映射
字段創建方式自動推斷手動預定義
靈活性
可控性
適合場景開發初期、數據結構不確定生產環境、數據結構穩定
性能影響可能產生不理想的映射可優化映射提升性能
維護成本低(初期)高(后期整理)高(前期)低(后期)
數據一致性可能不一致高度一致

3.4 最佳實踐建議

  • 開發階段:可以使用動態映射快速原型開發。

    PUT /dev_index
    {"mappings": {"dynamic": true}
    }
    
  • 過渡階段:使用動態模板(dynamic templates)控制自動映射。

    PUT /transition_index
    {"mappings": {"dynamic_templates": [{"strings_as_keywords": {"match_mapping_type": "string","mapping": {"type": "keyword"}}}]}
    }
    
  • 生產環境:推薦使用靜態映射。

    PUT /prod_index
    {"mappings": {"dynamic": "strict","properties": {// 明確定義所有字段}}
    }
    
  • 混合使用:可以結合兩者優勢。

    PUT /hybrid_index
    {"mappings": {"dynamic": "false",  # 不自動索引新字段,但存儲在_source"properties": {// 明確定義已知字段}}
    }
    

通過合理選擇映射策略,可以在靈活性和可控性之間取得平衡,為不同階段的業務需求提供最合適的解決方案。

4.映射修改詳解

在 Elasticsearch 中,映射創建后是可以修改的,但有重要的限制和注意事項。

4.1 可以修改的內容

  • 添加新字段:任何時候都可以向現有映射添加新字段。

    PUT /my_index/_mapping
    {"properties": {"new_field": { "type": "text" }}
    }
    
  • 修改某些字段屬性

    • 可以更新 fields 多字段設置
    • 可以修改 analyzersearch_analyzer 等分析相關設置
    • 可以修改 ignore_above(keyword 字段)
    • 可以修改 null_value 設置
  • 動態映射規則:可以更新動態模板(dynamic templates)

4.2 不可修改的內容

  • 字段數據類型:不能更改已有字段的數據類型。
    • 例如:不能將 text 改為 keyword,不能將 long 改為 integer
  • 已索引的字段:不能更改已索引字段的基本結構。
    • 例如:不能將單字段改為多字段。
  • 字段名稱:不能直接重命名字段。

4.3 修改映射的解決方案

當需要做不允許的修改時,可以考慮以下方案:

  • 重建索引(Reindex)

    • 創建新索引,定義新映射。
    • 使用 Reindex API 將數據從舊索引復制到新索引。
    • 示例:
      POST _reindex
      {"source": { "index": "old_index" },"dest": { "index": "new_index" }
      }
      
  • 使用別名(Alias)

    • 創建指向新索引的別名。
    • 無縫切換應用查詢到新索引。
    • 示例:
      POST _aliases
      {"actions": [{ "remove": { "index": "old_index", "alias": "my_alias" } },{ "add": { "index": "new_index", "alias": "my_alias" } }]
      }
      
  • 多字段(Multi-fields)

    • 為字段添加不同數據類型的多字段版本。
    • 示例:
      PUT /my_index/_mapping
      {"properties": {"my_field": {"type": "text","fields": {"keyword": { "type": "keyword" }}}}
      }
      

4.4 案例:將字符串字段從 text 改為 keyword

4.4.1 錯誤方式(直接修改會失敗)

PUT /my_index/_mapping
{"properties": {"category": { "type": "keyword" }  // 如果原先是text,這會報錯}
}

4.4.2 正確方式(通過重建索引)

// 1. 創建新索引
PUT /my_index_v2
{"mappings": {"properties": {"category": { "type": "keyword" }}}
}// 2. 重新索引數據
POST _reindex
{"source": { "index": "my_index" },"dest": { "index": "my_index_v2" }
}// 3. 切換別名
POST _aliases
{"actions": [{ "remove": { "index": "my_index", "alias": "products" } },{ "add": { "index": "my_index_v2", "alias": "products" } }]
}

4.5 注意事項

  • 生產環境謹慎操作:映射更改可能影響現有查詢和應用程序。
  • 停機時間考慮:重建大索引可能需要時間,規劃好維護窗口。
  • 版本兼容性:Elasticsearch 不同版本對映射修改的支持可能不同。
  • 監控影響:修改后監控集群性能和查詢結果。
  • 備份數據:重大映射修改前建議備份重要數據。
  • 測試環境驗證:先在測試環境驗證映射修改的效果。

通過合理規劃映射修改策略,可以在最小化影響的情況下實現索引結構的演進。

5.注意事項

  • 提前規劃映射:生產環境中應預先定義好映射,避免依賴動態映射
  • 避免映射爆炸
    • 設置 index.mapping.total_fields.limit(默認 1000)
    • 使用 dynamic: falsedynamic: strict 控制動態字段
  • 合理選擇數據類型
    • 需要全文搜索用 text,需要精確匹配/聚合用 keyword
    • 數值類型選擇最合適的范圍(如能用 integer 就不用 long
  • 元字段使用
    • 不要修改 _source 字段,它是文檔的原始 JSON
    • 使用 _routing 優化查詢性能
  • 映射更新限制
    • 已有字段的映射類型不能更改
    • 只能添加新字段或修改某些參數(如增加字段的 fields
  • 性能考慮
    • 避免過多的嵌套對象
    • 對于不搜索的字段設置 "index": false
  • 版本兼容性
    • Elasticsearch 7.x 及以后版本已移除映射類型概念
    • 升級時要注意 API 變化

通過合理設計映射,可以顯著提高 Elasticsearch 的查詢性能和存儲效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

serv00 ssh登錄保活腳本-郵件通知版

適用于自己有服務器情況,ssh定時登錄到serv00,并在登錄成功后發送郵件通知 msmtp 和 mutt安裝 需要安裝msmtp 和 mutt這兩個郵件客戶端并配置,參考如下文章前幾步是講配置這倆客戶端的,很簡單,不再贅述 用Shell腳本實…

前端 Electron 桌面應用學習筆記

前端 Electron 桌面應用學習筆記 介紹Electron是什么?為什么選擇Electron?創建你的第一個桌面應用程序啟動項目運行結果截圖打開調試面板方法生命周期函數常用配置配置窗口標題配置小圖標隱藏菜單欄關閉調試面板是否可以使用Node.js隱藏 Electron 標題、小圖標和菜單欄獲取窗…

LeetCode - 94. 二叉樹的中序遍歷

題目 94. 二叉樹的中序遍歷 - 力扣(LeetCode) 什么是中序遍歷 二叉樹的中序遍歷是按照"左-根-右"的順序訪問二叉樹中的所有節點。 具體過程: 先遍歷左子樹(遞歸)然后訪問根節點最后遍歷右子樹&#xff…

PyTorch——搭建小實戰和Sequential的使用(7)

import torch from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass TY(nn.Module):def __init__(self):"""初始化TY卷積神經網絡模型模型結構:3層卷積池化,2層全連接設計目標:處理32x32像素的…

C#、VB.net——如何設置窗體應用程序的外邊框不可拉伸

以Visual studio 2015為例,具體操作如下: 1、將窗體的“FormBorderStyle”屬性值修改為“FixedSingle”: 2、點擊“格式”——“鎖定控件”: 這樣生成的程序邊框即可固定住,無法拉伸。

深入了解NIO的優化實現原理

網絡 I/O 模型優化 網絡通信中,最底層的就是內核中的網絡 I/O 模型了。隨著技術的發展,操作系統內核的網絡模型衍生出了五種 I/O 模型,《UNIX 網絡編程》一書將這五種 I/O 模型分為阻塞式 I/O、非阻塞式 I/O、I/O 復用、信號驅動式 I/O 和異步…

【前端】vue3性能優化方案

以下是Vue 3性能優化的系統性方案,結合核心優化策略與實用技巧,覆蓋渲染、響應式、加載、代碼等多個維度: ?? 一、渲染優化 精準控制渲染范圍 v-if vs v-show: v-if:條件為假時銷毀DOM,適合低頻切換場景&…

在MATLAB中使用自定義的ROS2消息

簡明結論: 無論ROS2節點和MATLAB運行在哪,MATLAB本機都必須擁有自定義消息源碼并本地用ros2genmsg生成,才能在Simulink里訂閱這些消息。只要你想讓MATLAB或Simulink能識別自定義消息,必須把消息包源碼(.msg等)拷到本機指定目錄&a…

spring重試機制

數據庫死鎖處理與重試機制實現指南 1. 業務場景 1.1 問題現象 高并發批量數據處理時頻繁出現數據庫死鎖主要發生在"先刪除歷史數據,再重新計算"的業務流程中原有逐條處理方式:list.forEach(item -> { delete(); calculate(); }) 1.2 死…

QEMU源碼全解析 —— 塊設備虛擬化(24)

接前一篇文章:QEMU源碼全解析 —— 塊設備虛擬化(23) 本文內容參考: 《趣談Linux操作系統》 —— 劉超,極客時間 《QEMU/KVM源碼解析與應用》 —— 李強,機械工業出版社 特此致謝! QEMU寫入一個文件的完整過程 前邊用了十來篇文章的篇幅,解析了QEMU啟動過程中的存儲…

java中static學習筆記

較重要知識點 static修飾的變量是共享的在類加載時創建可以不通過實例來訪問靜態方法只能訪問靜態的成員和方法;而非靜態的可以訪問靜態的和非靜態的。靜態方法一般用在通用的方法,這樣方便調用,不然一個通用的方法每一次調用都要創建實例&a…

快刀集(1): 一刀斬斷視頻片頭廣告

一刀流:用一個簡單腳本,秒殺視頻片頭廣告,還你清爽觀影體驗。 1. 引子 作為一個愛生活、愛學習、愛收藏高清資源的老碼農,平時寫代碼之余看看電影、補補片,是再正常不過的事。 電影嘛,要沉浸,…

spring中的@KafkaListener 注解詳解

KafkaListener 是 Spring Kafka 提供的一個核心注解,用于標記一個方法作為 Kafka 消息的消費者。下面是對該注解的詳細解析: 基本用法 KafkaListener(topics "myTopic", groupId "myGroup") public void listen(String message)…

多區域協同的異地多活AI推理服務架構

🌐多區域協同的異地多活AI推理服務架構 #mermaid-svg-TTnpRKKC7k3twxhE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-TTnpRKKC7k3twxhE .error-icon{fill:#552222;}#mermaid-svg-TTnpRKKC7k3twxhE .er…

極客時間:在 Google Colab 上嘗試 Prefix Tuning

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

Android設備推送traceroute命令進行網絡診斷

文章目錄 工作原理下載traceroute for android推送到安卓設備執行traceroutetraceroute www.baidu.com Traceroute(追蹤路由) 是一個用于網絡診斷的工具,主要用于追蹤數據包從源主機到目標主機所經過的路由路徑,以及每一跳&#x…

【Linux應用】Linux系統日志上報服務,以及thttpd的配置、發送函數

【Linux應用】Linux系統日志上報服務,以及thttpd的配置、發送函數 文章目錄 thttpd服務安裝thttpd配置thttpd服務thttpd函數日志效果和文件附錄:開發板快速上手:鏡像燒錄、串口shell、外設掛載、WiFi配置、SSH連接、文件交互(RADX…

Linux 內核內存管理子系統全面解析與體系構建

一、前言: 為什么內存管理是核心知識 內存管理是 Linux 內核最核心也最復雜的子系統之一,其作用包括: 為軟件提供獨立的虛擬內存空間,實現安全隔離分配/回收物理內存資源,維持系統穩定支持不同類型的內存分配器,最優…

鼠標的拖動效果

1、變量的設置 let isDragging false; let startX; let startY; let endX; let endY; let box null;isDragging : 表示是否推拽startX、startY:表示起始坐標,相對于元素endX、endY:表示結束坐標,相對于元素box&…

SwaggerFuzzer:一款自動化 OpenAPI/Swagger 接口未授權訪問測試工具

SwaggerFuzzer 🌐 一款自動化 OpenAPI/Swagger 接口未授權訪問測試工具🚀 工具介紹:SwaggerFuzzer? 核心功能亮點🚀 快速使用🧰 支持參數 📌 項目結構📥 獲取與下載 🌐 一款自動化 …