2013-11-01 25 views
6

我正在使用Apache AvroApache Avro:地圖使用CharSequence作爲密鑰

我的模式有地圖類型:

{"name": "MyData", 
    "type" : {"type": "map", 
       "values":{ 
        "type": "record", 
        "name": "Person", 
        "fields":[ 
         {"name": "name", "type": "string"}, 
         {"name": "age", "type": "int"}, 

       ] 
       } 
       } 
} 

編譯模式,在genated Java類使用CharSequence作爲MapMyData關鍵後。

它使用起來非常不方便CharSequenceMap爲重點,有沒有辦法生成在Apache AvroMapString式按鍵?

附:

問題是,例如dataMap.containsKey("SOME_KEY")將返回即使false有這樣的關鍵在那裏,只是因爲它是CharSequence。此外,使用現有密鑰輸入地圖條目不會重複使用舊的密鑰。這就是爲什麼我說這是不方便使用CharSequence作爲關鍵。

+0

給出你對一個答案的評論:你是否確切地發現了什麼對你來說很重要?在中,你實際使用的'Map'是否使用非'String'鍵? – millimoose

+0

Millimoose,生成的Map使用CharSequence作爲鍵。 – Mellon

+0

默認情況下,生成的地圖使用Utf8,您可以選擇將其設置爲String。 CharSequence只是一個界面。 –

回答

2

不管它是否有可能迫使Avro的使用String,使用CharSequence直接是不好實現,因爲CharSequence不是Comparable<CharSequence>甚至不指定兩個相同的序列中的平等。我建議將此作爲對Avro的錯誤提交。

+0

事實上,即使在相當平凡的情況下('String'和'StringBuilder'),哈希碼也不匹配:http://ideone.com/cX76YN。 (它們用於'StringBuffer'和'StringBuilder',但這可能是後者大部分是前者的副本的同時刪除同步的結果。) – millimoose

+0

@millimoose'StringBuffer'和'StringBuilder'都擴展了受封裝保護的'AbstractStringBuilder'所以毫不奇怪他們的行爲是一致的。同意這是一個實施問題。 –

3

顯然,在默認情況下,Avro的使用CharSequence。我發現a way to configure it to convert to String

從Avro 1.6.0開始,有一個選項可以讓Avro始終執行到字符串的轉換。有幾種方法可以實現這一點。首先是架構中的avro.java.string屬性設置爲字符串:

  { "type": "string", "avro.java.string": "String" } 

我沒有測試過這一點。

+0

這是執行此操作的正確方法,並且此屬性用於處理此確切問題。 –

+0

這是每場配置?你如何做這個地圖的關鍵? 也鏈接死了。 – andresp

6

顯然,對於在Avro的1.6此問題的方法。你在你的項目的POM文件中指定的字符串類型:

<stringType>String</stringType> 

這是在這個問題提的是AVRO-803 ...雖然該插件的網頁文件並沒有反映這一點。

+0

根據這個問題,爲了增加傷害,所使用的CharSequence子類實際上是一個Avro特定的類('Utf8'),他們可以很容易地通過可串/等同於'String'來減少一些痛苦。 – millimoose

+0

這是一個很好的觀點。如果Avro尚未被添加,這可能是一個值得改變的地方。另一方面,CharSequence並不保證平等行爲,所以也許最好在這種情況下使用toString()。 –

6

This JIRA discussion是相關的。 CharSequence仍然使用的主要點是向後兼容性

而像查爾斯·福賽斯指出的那樣,已添加字符串時是必要的,在架構設置字符串屬性一種解決方法。

{ "type": "string", "avro.java.string": "String" } 

這裏的默認類型是他們自己的Utf8類。除了手動規範和the pom.xml setting,甚至有一個Avro的工具編譯選項吧,-string選項:

java -jar avro-tools.1.7.5.jar compile -string schema /path/to/schema . 
0

一個快速解決方案(該值類型可以是其它的對象,現在我):

Map<String, String> convertToStringMap(Map<CharSequence, CharSequence> map){ 
    if (null == map){ 
     return null; 
    } 
    HashMap<String, String> result = new HashMap<String, String>(); 
    for(CharSequence key: map.keySet()){ 
     CharSequence k_value = map.get(key); 
     String s_key = key.toString(); 
     String s_value = k_value.toString(); 
     result.put(s_key, s_value); 
    } 
    return result; 
} 
0

我想明確地將字符串轉換爲Utf8將工作。 「some_key」 - >新建Utf8(「some_key」)並將其用作地圖的關鍵字。