本文將接着上文繼續介紹如何使用Hive將數據寫入到ElasticSearch中。在使用前同樣需要加入 elasticsearch-hadoop-2.3.4.jar
依賴,具體請參見前文介紹。我們先在Hive里面建個名為iteblog
的表,如下:
CREATE EXTERNAL TABLE iteblog ( id bigint, name STRING) STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES('es.resource' = 'iteblog/iteblog', 'es.nodes'='www.iteblog.com','es.port'='9003');
建完表之后我們可以看下Hive是怎么存儲這樣的表格:
hive> show create table iteblog; OK CREATE EXTERNAL TABLE `iteblog`( `id` bigint COMMENT 'from deserializer', `name` string COMMENT 'from deserializer') ROW FORMAT SERDE 'org.elasticsearch.hadoop.hive.EsSerDe' STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' WITH SERDEPROPERTIES ( 'serialization.format'='1') LOCATION 'hdfs://user/iteblog/hive/warehouse/iteblog.db/iteblog' TBLPROPERTIES ( 'COLUMN_STATS_ACCURATE'='false', 'es.nodes'='www.iteblog.com', 'es.port'='9003', 'es.resource'='iteblog/iteblog', 'numFiles'='0', 'numRows'='-1', 'rawDataSize'='-1', 'totalSize'='0', 'transient_lastDdlTime'='1478248148') Time taken: 0.148 seconds, Fetched: 21 row(s)
我們可以看到Hive對里面的字段注釋是 from deserializer,如果是正常的Hive表將沒有這些信息;而且我們可以發現 ROW FORMAT SERDE
已經變成了 org.elasticsearch.hadoop.hive.EsSerDe
,在TBLPROPERTIES
里面記錄了一些鏈接ElasticSearch需要的參數配置。好了,現在我們在這個表里面導一些數據:
hive> insert into table iteblog select * from test limit 100;
上面的SQL運行完之后我們可以看到表所在的HDFS目錄是沒有數據的:
hive > dfs -ls /user/iteblog/hive/warehouse/iteblog.db/iteblog; hive >
我們到ElasticSearch里面可以發現已經多了一個index和type,就是我們在建表時指定的 es.resource
,而且ElasticSearch為我們生成type的mapping如下:
{
"iteblog"
: {
"properties"
: {
"name"
: {
"type"
:
"string"
},
"id"
: {
"type"
:
"long"
}
}
}
}
|
這就Hive表里面的字段,類型都對應了。但是我們發現ElasticSearch中的 iteblog/iteblog
每行數據對應的id都是隨機生成的,不過我們可以在建Hive表的時候加上 es.mapping.id
參數來指定我們自定義的id如下:
CREATE
EXTERNAL
TABLE
iteblog (
id
bigint
,
name
STRING)
STORED
BY
'org.elasticsearch.hadoop.hive.EsStorageHandler'
TBLPROPERTIES(
'es.resource'
=
'iteblog/iteblog'
,
'es.nodes'
=
'www.iteblog.com'
,
'es.port'
=
'9003'
,
'es.mapping.id'
=
'id'
);
|
這樣ElasticSearch中的 iteblog/iteblog
對應的id將會和Hive中的id字段一一對應。當然其他的字段也可以設置相應的mapping,可以通過 es.mapping.names
參數實現。
如何存Json數據
如果我們Hive里面的字段是Json數據,我們希望在ElasticSearch中解析這個json數據,然后在ElasticSearch中將解析的數據存起來,比如我們的Json數據格式為:{"id":"123","name":"iteblog"}
,我們可以在建Hive表的時候加上 es.input.json
參數,這樣ElasticSearch會解析這個json數據,如下:
CREATE
EXTERNAL
TABLE
iteblog (
json STRING)
STORED
BY
'org.elasticsearch.hadoop.hive.EsStorageHandler'
TBLPROPERTIES(
'es.resource'
=
'iteblog/iteblog'
,
'es.nodes'
=
'www.iteblog.com'
,
'es.port'
=
'9003'
,
'es.input.json'
=
'yes'
);
|
這樣ElasticSearch為我們生成的mapping為:
{
"iteblog"
: {
"properties"
: {
"name"
: {
"type"
:
"string"
},
"id"
: {
"type"
:
"string"
}
}
}
}
|
而不是
{
"iteblog"
: {
"properties"
: {
"json"
: {
"type"
:
"string"
}
}
}
}
|
es.input.json
配置,這時候在Hive里面查數會發現數據都是NULL:
hive >
select
*
from
iteblog limit 10;
OK
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
Time
taken: 0.057 seconds, Fetched: 10 row(s)
|
數據為json的時候我們同樣可以指定ElasticSearch的id生成的規則,如下:
CREATE
EXTERNAL
TABLE
iteblog (
json STRING)
STORED
BY
'org.elasticsearch.hadoop.hive.EsStorageHandler'
TBLPROPERTIES(
'es.resource'
=
'iteblog/iteblog'
,
'es.nodes'
=
'www.iteblog.com'
,
'es.port'
=
'9003'
,
'es.input.json'
=
'yes'
,
'es.mapping.id'
=
'id'
);
|
這樣就會把Json里面的id當作ElasticSearch中的id。
動態處理type
有時候我們可能希望根據數據的類別不一樣來將數據存放到ElasticSearch中不同的type中,我們可以通過如下設置實現
CREATE
EXTERNAL
TABLE
iteblog (
id
bigint
,
name
STRING,
type STRING)
STORED
BY
'org.elasticsearch.hadoop.hive.EsStorageHandler'
TBLPROPERTIES(
'es.resource'
=
'iteblog/{type}'
,
'es.nodes'
=
'www.iteblog.com'
,
'es.port'
=
'9003'
);
|
這樣ElasticSearch會自動獲取Hive中的type字段的值,然后將不同type的數據存放到ElasticSearch中不同的type中。如果Hive中的字段是json格式,比如 {"id":"123","name":"iteblog","type":"A"}
,我們同樣可以通過下面設置實現:
CREATE
EXTERNAL
TABLE
iteblog (
json STRING)
STORED
BY
'org.elasticsearch.hadoop.hive.EsStorageHandler'
TBLPROPERTIES(
'es.resource'
=
'iteblog/{type}'
,
'es.nodes'
=
'www.iteblog.com'
,
'es.port'
=
'9003'
,
'es.input.json'
=
'yes'
);
|
這樣ElasticSearch會自動為我們解析json中的type字段的值,然后決定將這條記錄放到ElasticSearch中對應的type中。
Hive類型和ElasticSearch類型映射
Hive類型 | Elasticsearch類型 |
---|---|
void | null |
boolean | boolean |
tinyint | byte |
smallint | short |
int | int |
bigint | long |
double | double |
float | float |
string | string |
binary | binary |
timestamp | date |
struct | map |
map | map |
array | array |
union | 目前不支持 |
decimal | string |
date | date |
varchar | string |
char | string |