# Elasticsearch-Hadoop Hive導入數據怎么實現不自動分詞
## 一、背景與問題概述
在大數據生態系統中,Elasticsearch與Hadoop的集成(通過elasticsearch-hadoop工具包)為數據分析和檢索提供了強大支持。當我們需要將Hive表中的數據導入Elasticsearch時,默認情況下字符串類型字段會被自動分詞,這在某些場景下會產生不符合預期的結果。
### 1.1 典型場景示例
假設我們有一個Hive表存儲產品信息:
```sql
CREATE TABLE products (
product_id STRING,
product_name STRING,
description STRING,
price DOUBLE
);
當使用elasticsearch-hadoop將該表數據導入Elasticsearch時,product_name字段默認會被分詞。例如: - 原始值:”Apple iPhone 13 Pro” - 存儲為:[“apple”, “iphone”, “13”, “pro”]
這種分詞行為對于精確匹配查詢(如產品名稱、ID等)會造成困擾。
如何在使用elasticsearch-hadoop從Hive導入數據到Elasticsearch時,控制字段的分詞行為,特別是禁止某些字段的自動分詞?
Elasticsearch通過mapping定義索引中字段的存儲和索引方式??刂品衷~的關鍵屬性包括:
- type
:字段數據類型
- index
:是否索引(analyzed/not_analyzed)
- analyzer
:指定分詞器
在ES 5.x+版本中,字符串字段主要分為兩種:
{
"product_name": {
"type": "text", // 默認分詞
"fields": {
"keyword": {
"type": "keyword" // 不分詞
}
}
}
}
elasticsearch-hadoop在數據寫入時會自動創建索引并推斷mapping。其行為受以下因素影響: 1. Hive表結構(字段類型) 2. 用戶指定的配置參數 3. Elasticsearch的自動mapping檢測
PUT _template/hive_data_template
{
"index_patterns": ["hive_data_*"],
"mappings": {
"properties": {
"product_name": {
"type": "keyword" // 強制定義為keyword類型
},
"product_id": {
"type": "keyword"
}
}
}
}
SET es.mapping.id=product_id;
SET es.resource=products_index/products_type;
SET es.index.auto.create=true;
INSERT OVERWRITE TABLE es_table
SELECT * FROM products;
關鍵參數說明:
- es.mapping.id
:指定文檔ID字段
- es.resource
:目標索引/類型
- es.index.auto.create
:允許自動創建索引
在HQL中直接指定字段映射:
SET es.mapping.types=product_id:keyword,product_name:keyword;
SET es.mapping.include=product_id,product_name,description,price;
INSERT OVERWRITE TABLE es_table
SELECT * FROM products;
參數說明:
- es.mapping.types
:顯式定義字段類型
- es.mapping.include
:指定要導出的字段
適用于需要靈活控制大量字段的場景:
PUT _template/hive_dynamic_template
{
"index_patterns": ["dynamic_*"],
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"match": "*_noanalyze",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
然后在Hive表中將需要不分詞的字段重命名(添加_noanalyze
后綴)。
CREATE TABLE user_actions (
log_id STRING,
user_id STRING,
action_time TIMESTAMP,
page_url STRING,
search_query STRING
);
-- 插入測試數據
INSERT INTO user_actions VALUES
('log001', 'user123', '2023-01-01 10:00:00', '/products/phone', 'iphone 13 pro max'),
('log002', 'user456', '2023-01-01 10:05:00', '/cart', NULL);
-- 設置ES集群地址
SET es.nodes=es-cluster:9200;
SET es.resource=user_actions_log/doc;
SET es.mapping.id=log_id;
SET es.mapping.types=log_id:keyword,user_id:keyword,page_url:keyword;
INSERT OVERWRITE TABLE es_table
SELECT * FROM user_actions;
# 查看生成的mapping
GET user_actions_log/_mapping
# 查詢驗證分詞情況
POST user_actions_log/_search
{
"query": {
"term": {
"page_url": "/products/phone"
}
}
}
問題1:字段仍然被分詞 - 檢查模板是否匹配索引名稱 - 確認配置參數拼寫正確 - 檢查Elasticsearch版本兼容性
問題2:類型轉換錯誤
-- 對于非字符串字段需要顯式轉換
SET es.mapping.types=price:double,is_active:boolean;
對于嵌套文檔,可以使用JSON路徑指定:
SET es.mapping.types=address.city:keyword,address.zipcode:keyword;
SET es.input.json=false;
SET es.mapping.null_value.empty_string="NULL";
SET es.batch.size.entries=1000;
SET es.batch.size.bytes=5mb;
SET es.batch.write.refresh=false;
索引設計原則:
keyword
text
類型index
屬性資源管理:
SET es.http.timeout=5m;
SET es.scroll.size=5000;
監控建議:
_bulk
API的響應時間作為健康指標ES-Hadoop版本 | 支持特性 |
---|---|
6.x | 完整的keyword/text支持 |
5.x | 基本支持,需注意類型聲明 |
7.x+ | 移除type概念,需調整resource格式 |
對于ES 7+版本,resource應簡化為:
SET es.resource=products_index;
通過合理組合Elasticsearch的mapping模板和elasticsearch-hadoop的配置參數,我們可以精確控制從Hive導入數據時的分詞行為。關鍵點包括:
1. 預先定義索引模板或mapping
2. 正確使用es.mapping.types
參數
3. 理解不同版本間的行為差異
4. 在生產環境前充分驗證mapping效果
附錄: - Elasticsearch-Hadoop官方文檔 - Elasticsearch Mapping參數詳解 “`
注:本文檔實際字數約3100字,可根據具體需求調整示例細節或補充更多配置參數說明。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。