您好,登录后才能下订单哦!
# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。