2013-11-01 10 views
6

मैं Apache Avro का उपयोग कर रहा हूं।अपाचे एवरो: नक्शा CharSequence का उपयोग करता है कुंजी

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

       ] 
       } 
       } 
} 

बाद स्कीमा, genated जावा वर्ग उपयोग CharSequenceMapMyData के लिए कुंजी के रूप में संकलन:

मेरे स्कीमा नक्शा प्रकार है।

यह बहुत कुंजी के रूप में Map में CharSequence उपयोग करने के लिए असुविधाजनक है, वहाँ एक रास्ता Apache Avro में Map के लिए String प्रकार कुंजी उत्पन्न करने के लिए है?

पीएस

समस्या है कि, उदाहरण के लिए dataMap.containsKey("SOME_KEY") इच्छा देता है वहाँ इस तरह के महत्वपूर्ण है, सिर्फ इसलिए कि यह CharSequence है false भले ही है। इसके अलावा, किसी मौजूदा कुंजी के साथ नक्शा प्रविष्टि डालें, पुराने को स्थानांतरित नहीं करता है। यही कारण है कि मैं कहता हूं कि CharSequence कुंजी के रूप में उपयोग करना असुविधाजनक है।

+0

एक उत्तर पर आपकी टिप्पणी को देखते हुए: क्या आपको पता चला कि आपके लिए क्या तोड़ रहा है? जैसा कि, क्या आप 'मानचित्र' वास्तव में गैर-'स्ट्रिंग' कुंजी का उपयोग करते हैं? – millimoose

+0

मिलीमूज़, उत्पन्न नक्शा कुंजी के लिए CharSequence का उपयोग करें। – Mellon

+0

जेनरेट किया गया मानचित्र डिफ़ॉल्ट रूप से Utf8 का उपयोग करता है, और आप इसे स्ट्रिंग बनाना चुन सकते हैं। CharSequence सिर्फ एक इंटरफ़ेस है। –

उत्तर

2

कि क्या यह एक String उपयोग करने के लिए, CharSequence का उपयोग कर एवरो मजबूर करने के लिए संभव है की परवाह किए बिना सीधे एक बुरा कार्यान्वयन क्योंकि CharSequenceComparable<CharSequence> नहीं है और यहां तक ​​कि दो समान दृश्यों की समानता को निर्दिष्ट नहीं करता है। मैं इसे एवरो के खिलाफ एक बग के रूप में दर्ज करने का सुझाव देता हूं।

+0

वास्तव में यहां तक ​​कि काफी मामूली मामला ('स्ट्रिंग' और 'स्ट्रिंगबिल्डर') में हैश कोड मेल नहीं खाते: http://ideone.com/cX76YN। (वे 'स्ट्रिंगबफर' और 'स्ट्रिंगबिल्डर' के लिए करते हैं, लेकिन शायद यह बाद में सिंक्रनाइज़ेशन के साथ पूर्व की एक प्रति होने का एक परिणाम है।) – millimoose

+0

@ मिलिमोस 'स्ट्रिंगबफर' और 'स्ट्रिंगबिल्डर' दोनों पैकेज-संरक्षित 'सारस्ट्रिंगबिल्डर' का विस्तार करते हैं तो कोई आश्चर्य नहीं कि वे एक जैसे कार्य करते हैं। सहमत हैं कि यह एक कार्यान्वयन समस्या है। –

3

जाहिर है, डिफ़ॉल्ट रूप से, एवरो CharSequence का उपयोग करता है। मुझे a way to configure it to convert to String

एवरो 1.6.0 आगे से, एरो हमेशा स्ट्रिंग में रूपांतरण करने का विकल्प होता है। इसे प्राप्त करने के कुछ तरीके हैं। पहली स्ट्रिंग के लिए स्कीमा में avro.java.string गुण सेट करने के लिए है:

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

मैं इस परीक्षण नहीं किया।

+0

यह करने का यह सही तरीका है, और यह संपत्ति इस सटीक समस्या से निपटने के लिए मौजूद है। –

+0

यह प्रति फ़ील्ड कॉन्फ़िगरेशन है? मानचित्र कुंजी के लिए आप यह कैसे करते हैं? भी, लिंक मर चुका है। – andresp

6

जाहिर है, एवरो 1.6 में इस समस्या के लिए एक समाधान है। आप अपने प्रोजेक्ट की पोम फ़ाइल में स्ट्रिंग प्रकार निर्दिष्ट करें:

<stringType>String</stringType> 

यह इस मुद्दे में बताया गया है AVRO-803 है ... हालांकि प्लगइन के वेब प्रलेखन इस प्रतिबिंबित नहीं करता।

+0

उस मुद्दे के मुताबिक, 'CharSequence' subclass को चोट पहुंचाने के अपमान को जोड़ने के लिए वास्तव में एक एवरो-विशिष्ट वर्ग (' यूटीएफ 8') है जिसे वे कुछ दर्द को कम करने के लिए आसानी से 'स्ट्रिंग' के लिए हैशबल/समेकित बना सकते थे। – millimoose

+0

यह एक अच्छा मुद्दा है। यह एवरो के लिए एक सार्थक परिवर्तन हो सकता है अगर इसे पहले ही जोड़ा नहीं जा चुका है। दूसरी तरफ, CharSequence समानता व्यवहार की गारंटी नहीं देता है, इसलिए शायद उन मामलों में ToString() का उपयोग करना बेहतर है। –

6

This JIRA discussion प्रासंगिक है। CharSequence का मुख्य बिंदु अभी भी उपयोग किया जा रहा है पिछड़ा-संगतता है।

और चार्ल्स फोर्सिथ की तरह इंगित किया गया है कि स्कीमा में स्ट्रिंग प्रॉपर्टी सेट करके स्ट्रिंग आवश्यक होने पर वर्कअराउंड जोड़ा गया है।

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

डिफ़ॉल्ट प्रकार यहां उनका स्वयं का यूटीएफ 8 वर्ग है।मैनुअल विनिर्देश और the pom.xml setting के अलावा, वहाँ, यहां तक ​​कि एक एवरो उपकरण इसके लिए विकल्प संकलन है -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

मुझे लगता है कि स्पष्ट रूप से स्ट्रिंग टू यूटीएफ 8 में काम करेगा। "some_key" -> नया Utf8 ("some_key") और मानचित्र के लिए अपनी कुंजी के रूप में इसका उपयोग करें।

संबंधित मुद्दे