2015-09-18 6 views
5

मैं सर्वर लॉग से निपट रहा हूं जो JSON प्रारूप हैं, और मैं अपने लॉग को एडब्ल्यूएस एस 3 पर पैराक्वेट प्रारूप में स्टोर करना चाहता हूं (और पैराक्वेट को एवरो स्कीमा की आवश्यकता है)। सबसे पहले, सभी लॉगों में फ़ील्ड का एक सामान्य सेट होता है, दूसरा, सभी लॉग में बहुत सारे वैकल्पिक फ़ील्ड होते हैं जो सामान्य सेट में नहीं होते हैं।एवरो में मानचित्र के साथ रिकॉर्ड कैसे मिलाएं?

{ "ip": "172.18.80.109", "timestamp": "2015-09-17T23:00:18.313Z", "message":"blahblahblah"} 
{ "ip": "172.18.80.112", "timestamp": "2015-09-17T23:00:08.297Z", "message":"blahblahblah", "microseconds": 223} 
{ "ip": "172.18.80.113", "timestamp": "2015-09-17T23:00:08.299Z", "message":"blahblahblah", "thread":"http-apr-8080-exec-1147"} 

तीन लॉग के सभी 3 साझा क्षेत्रों है: ip, timestamp और message, लॉग में से कुछ इस तरह के microseconds और thread के रूप में अतिरिक्त क्षेत्रों, है

उदाहरण के लिए, follwoing तीन लॉग नहीं है।

अगर मैं निम्न स्कीमा का उपयोग तो मैं सभी अतिरिक्त फ़ील्ड .:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "String"}, 
    {"name": "message", "type": "string"} 
] 
} 

और निम्न स्कीमा खो देंगे ठीक काम करता है:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "String"}, 
    {"name": "message", "type": "string"}, 
    {"name": "microseconds", "type": [null,long]}, 
    {"name": "thread", "type": [null,string]} 
] 
} 

लेकिन केवल समस्या यह है कि मैं नहीं है वैकल्पिक फ़ील्ड के सभी नामों को तब तक जानें जब तक कि मैं सभी लॉग स्कैन नहीं करता, इसके अलावा, भविष्य में नए अतिरिक्त फ़ील्ड भी होंगे।

तो मैं एक विचार है कि record और map को जोड़ती है बाहर लगता है:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "String"}, 
    {"name": "message", "type": "string"}, 
    {"type": "map", "values": "string"} // error 
] 
} 

दुर्भाग्य से यह संकलन नहीं होगा:

Exception in thread "main" org.apache.avro.SchemaParseException: No field name: {"type":"map","values":"long"} 
    at org.apache.avro.Schema.getRequiredText(Schema.java:1305) 
    at org.apache.avro.Schema.parse(Schema.java:1192) 
    at org.apache.avro.Schema$Parser.parse(Schema.java:965) 
    at org.apache.avro.Schema$Parser.parse(Schema.java:932) 
    at org.apache.avro.tool.SpecificCompilerTool.run(SpecificCompilerTool.java:73) 
    at org.apache.avro.tool.Main.run(Main.java:84) 
    at org.apache.avro.tool.Main.main(Main.java:73) 
:

java -jar avro-tools-1.7.7.jar compile schema example.avro . 

यह एक त्रुटि बाहर फेंक होगा

क्या एवरो प्रारूप में जेएसओएन तारों को स्टोर करने का कोई तरीका है जो flexib हैं अज्ञात वैकल्पिक क्षेत्रों से निपटने के लिए le?

असल में यह स्कीमा विकास समस्या है, स्पार्क Schema Merging द्वारा इस समस्या से निपट सकता है। मैं हडोप के साथ एक समाधान की तलाश में हूं।

+0

आपके मानचित्र का कोई नाम विशेषता नहीं है। इसे एक दें। :) – oakad

+0

मुझे लगता है कि आप कभी भी एरो का प्रयास नहीं करते हैं। यह काम नहीं करेगा। '{" नेमस्पेस ":" example.avro ", " टाइप ":" रिकॉर्ड ", " नाम ":" लॉग ", " फ़ील्ड ": [ {" name ":" ip "," type ": "स्ट्रिंग"}, {"name": "टाइमस्टैम्प", "टाइप": "स्ट्रिंग"}, {"name": "message", "type": "string"}, {"name": " addtional "," प्रकार ":" मानचित्र "," मान ":" स्ट्रिंग "} ] }' – soulmachine

उत्तर

5

नक्शा प्रकार एवरो शब्दावली में एक "जटिल" प्रकार है। नीचे स्निपेट काम करता है:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "string"}, 
    {"name": "message", "type": "string"}, 
    {"name": "additional", "type": {"type": "map", "values": "string"}} 
    ] 
} 
+0

धन्यवाद! यह स्कीमा संकलन पास करेगा। यह स्कीमा सभी वैकल्पिक फ़ील्ड को 'addtional' फ़ील्ड में रखती है, उदाहरण के लिए, '{" ip ":" 172.18.80.109 "," टाइमस्टैंप ":" 2015-09-17T23: 00: 18.313Z "," message ":" blah ब्लैश "," addtional ": {" microseconds ":" 123 "," thread ":" http-apr-8080-exec-1147 "}} ', लेकिन मैं सामान्य क्षेत्रों के समान स्तर पर सभी वैकल्पिक फ़ील्ड चाहता हूं, मेरे प्रश्न में तीन उदाहरण लॉग की तरह। – soulmachine

+0

एवरो में रिकॉर्ड को पूर्व निर्धारित फ़ील्ड की एक निश्चित संख्या वाले ऑब्जेक्ट के रूप में परिभाषित किया जाता है। वैकल्पिक रूप से, अपने मानचित्र को शीर्ष स्तर की वस्तु के रूप में रखें और अपने सभी फ़ील्ड को उस मानचित्र में चाबियों के रूप में देखें। – oakad

+0

यदि मैं 'मानचित्र' का उपयोग शीर्ष-स्तरीय प्रकार के रूप में करता हूं, उदा।, '{" टाइप ":" मैप "," वैल्यू ":" स्ट्रिंग "}', फिर सभी फ़ील्ड्स को 'स्ट्रिंग' प्रकार होना चाहिए, यदि विभिन्न प्रकार के फ़ील्ड हैं, तो 'मैप' असहाय है। – soulmachine

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