通過Hive將數據寫入到ElasticSearch


本文將接着上文繼續介紹如何使用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"
             }
         }
     }
}
如果Hive中的數據是Json字段,但是在寫ElasticSearch的時候使用了  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


免責聲明!

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



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