2016-03-29 16 views
5

मैं BigQuery (और sql) में नया हूं और एक टेबल सेट करने की कोशिश कर रहा हूं जहां प्रत्येक पंक्ति में message कॉलम (स्ट्रिंग) और metadata कॉलम (दोहराया गया) शामिल है। मैं मेटाडेटा कॉलम का उपयोग करना चाहता हूं ताकि मैं उन संदेशों के लिए क्वेरी कर सकूं जो कुछ मेटाडेटा पैरामीटर से मेल खाते हैं।क्वेरी BigQuery नेस्टेड/दोहराए गए फ़ील्ड

उदाहरण के लिए, मेरा संदेश स्ट्रिंग है:

Hi honey, I'm home!

और मेटाडाटा स्तंभ मनमाने ढंग से कुंजी/मान जोड़े उस संदेश का वर्णन है:

{"category": "personal", "message_type": "salutation"}

यह मैं करने की अनुमति होगी बड़ी पूछताछ करें:

मुझे सभी संदेश लौटाएं personal के category (या personal की message_type, आदि)

दोहराना करने के लिए, मेटाडाटा कुंजी संभावित हर संदेश की उस पंक्ति सम्मिलित किया जाता है के लिए अलग होगा (जैसे कि category की बजाय एक नई पंक्ति में favorite_color की मेटाडेटा कुंजी हो सकती है)।

[ 
{"name": "message", "type": "string", "mode": "required"} 
{"name": "metadata", "type": "record", "mode": "repeated", "fields": [ {"name": "key", 
                     "type": "string", 
                     "mode": "required"}, 
                     {"name": "value", 
                     "type": "string", 
                     "mode": "required"}]} 
] 

स्कीमा को उम्मीद है कि हर मेटाडाटा प्रविष्टि/पंक्ति कॉलम key कहा जाता है और स्तंभ value कहा जाता है:

यहाँ स्कीमा कि मैं आदेश मेटाडाटा लचीलापन है कि मैं इच्छा का समर्थन करने के साथ आया है। यह काम तो ठीक करता है।

message     | metadata_key | metadata_value 
------------------------------------------------------------ 
Hi honey, I'm home!  category    personal 
Hi honey, I'm home!  message_type   salutation 

मैं पता लगा कि कैसे एक भी मेटाडाटा मूल्य के खिलाफ क्वेरी करने के लिए इस तरह के category = personal के रूप में:

दिलचस्प बात यह है BigQuery दो पंक्तियों के रूप में मेरा संदेश पंक्ति (? जो मुझे लगता है कि कहा जाता है "सपाट") का प्रतिनिधित्व करता है:

SELECT * FROM [table.test] 
WHERE 
metadata.key="category" AND metadata.value="personal" 

मैं एक ही पंक्ति वापस पाने:

message     | metadata_key | metadata_value 
------------------------------------------------------------ 
Hi honey, I'm home!  category    personal 

यह बहुत अच्छा है!

मुझे सभी संदेशों को जो personal के category और salutation

की message_type यह निम्नलिखित है लायें: लेकिन, मैं कैसे एक अधिक जटिल क्वेरी है कि इस तरह के रूप में कई मेटाडाटा मापदंडों के खिलाफ मेल खाता निर्माण करने के लिए पता नहीं है क्वेरी वापस नहीं करता है कुछ भी:

SELECT * FROM [table.test] 
WHERE 
metadata.key="category" AND metadata.value="personal" AND 
metadata.key="message_type" AND metadata.value="salutation" 

मुझे लगता है इस वजह से bigquery दो पंक्तियों (प्रत्येक नेस्टेड मेटाडाटा पंक्ति के लिए एक) में अपने एक संदेश पंक्ति टूट रहा है। इसका स्पष्ट अर्थ यह है कि मेरी क्वेरी कभी भी एक पंक्ति से मेल नहीं खा पाएगी क्योंकि मैं दो अलग मेटाडेटा पंक्तियों के खिलाफ मिलान करने की कोशिश कर रहा हूं (यानी मैं मेटाडाटा.की के लिए एक ही समय में दो अलग-अलग मानों के बराबर होने के लिए कह रहा हूं, और मेटाडेटा एक ही समय में अलग-अलग मूल्यों के बराबर होना चाहिए। इसलिए मैं कुछ हद तक स्टंप हूं कि मेरी क्वेरी को उचित तरीके से कैसे बनाया जाए।

आदर्श रूप से मैं BigQuery को एकल पंक्ति (मूल उदाहरण पंक्ति जिसे मैंने शुरू किया) वापस करने के लिए चाहूंगा, क्योंकि यह मेरी क्वेरी की दो मेटाडेटा आवश्यकताओं को पूरा करता है।

मुझे लगता है कि मुझे ग्रुप बाय, फ्लैटन, अंदर, unflatten, आदि के कुछ संयोजन की आवश्यकता है। संभावनाओं/संरचना का संयोजन इस एसक्यूएल/bigquery नौसिखिया के लिए कुछ हद तक चुनौतीपूर्ण है। किसी भी मदद की सराहना की :)

उत्तर

5

नीचे का प्रयास करें - विकल्प
का सिर्फ एक यह योग कितने "से मेल खाता है आप प्रत्येक पंक्ति में है और सभी कि क्या (यह मामलों में - 2)। यह आउटपुट सुंदर सरल

SELECT *, 
SUM((metadata.key="category" AND metadata.value="personal") 
OR (metadata.key="message_type" AND metadata.value="salutation") 
) WITHIN RECORD AS check, 
FROM [table.test] 
HAVING check = 2 

इसका क्लीनर संस्करण

SELECT * 
FROM [table.test] 
OMIT RECORD IF 
SUM((metadata.key="category" AND metadata.value="personal") 
OR (metadata.key="message_type" AND metadata.value="salutation") 
) != 2  
जैसा होगा
संबंधित मुद्दे