2016-03-11 21 views
9

Tôi gặp sự cố khi tham gia vào trường lồng nhau được lặp lại trong khi vẫn duy trì cấu trúc hàng gốc trong BigQuery.bigquery tham gia vào lồng nhau lặp đi lặp lại

Ví dụ của tôi, tôi sẽ gọi hai bảng được nối AB.

Đĩa hát trong bảng A nhìn cái gì đó như:

{ 
    "url":"some url", 
    "repeated_nested": [ 
    {"key":"some key","property":"some property"} 
    ] 
} 

và các bản ghi trong bảng B nhìn cái gì đó như:

{ 
    "key":"some key", 
    "property2": "another property" 
} 

Tôi hy vọng tìm được một cách để tham gia vào dữ liệu này với nhau để tạo ra một hàng trông giống như:

{ 
    "url":"some url", 
    "repeated_nested": [ 
    { 
     "key":"some key", 
     "property":"some property", 
     "property2":"another property" 
    } 
    ] 
} 

Truy vấn đầu tiên tôi đã thử là:

SELECT 
    url, repeated_nested.key, repeated_nested.property, repeated_nested.property2 
FROM A 
    AS lefttable 
LEFT OUTER JOIN B 
    AS righttable 
    ON lefttable.key=righttable.key 

Điều này không hiệu quả vì BQ không thể tham gia vào các trường lồng nhau lặp lại. Không có số nhận dạng duy nhất cho mỗi hàng. Nếu tôi đã làm một số FLATTEN trên repeated_nested thì tôi không chắc chắn làm cách nào để đưa hàng gốc được đặt lại chính xác.

Dữ liệu như vậy là url sẽ luôn có cùng trường repeated_nested với nó. Do đó, tôi đã có thể làm cho một workaround sử dụng một UDF để loại cuộn lên đối tượng lồng nhau lặp đi lặp lại này thành một chuỗi JSON và rồi cuộn nó lại:

SELECT url, repeated_nested.key, repeated_nested.property, repeated_nested.property2 

FROM 
JS(
    (
    SELECT basetable.url as url, repeated_nested 
    FROM A as basetable 

    LEFT JOIN (
     SELECT url, CONCAT("[", GROUP_CONCAT_UNQUOTED(repeated_nested_json, ","), "]") as repeated_nested 
     FROM 
     (
     SELECT 
      url, 
      CONCAT(
       '{"key": "', repeated_nested.key, '",', 
       ' "property": "', repeated_nested.property, '",', 
       ' "property2": "', mapping_table.property2, '"', 
       '}' 
      ) 
     ) as repeated_nested_json 
     FROM (
      SELECT 
      url, repeated_nested.key, repeated_nested.property 
      FROM A 
      GROUP BY url, repeated_nested.key, repeated_nested.property 
     ) as urltable 

     LEFT OUTER JOIN [SDF.alchemy_to_ric] 
      AS mapping_table 
      ON urltable.repeated_nested.key=mapping_table.key 
    ) 
     GROUP BY url 
    ) as companytable 
    ON basetable.url = urltable.url 
), 

    // input columns: 
    url, repeated_nested_json, 

    // output schema: 
    "[{'name': 'url', 'type': 'string'}, 
    {'name': 'repeated_nested_json', 'type': 'RECORD', 'mode':'REPEATED', 'fields': 
    [ { 'name': 'key', 'type':'string' }, 
     { 'name': 'property', 'type':'string' }, 
     { 'name': 'property2', 'type':'string' }] 
    }]", 

    // UDF: 
    "function(row, emit) { 
    parsed_repeated_nested = []; 
    try { 
     if (row.repeated_nested_json != null) { 
      parsed_repeated_nested = JSON.parse(row.repeated_nested_json); 
     } 
    } catch (ex) { } 

    emit({ 
     url: row.url, 
     repeated_nested: parsed_repeated_nested 
    }); 
    }" 
) 

Giải pháp này hoạt động tốt cho các bảng nhỏ. Nhưng các bảng thực tế mà tôi đang làm việc có nhiều cột hơn trong ví dụ trên. Khi có các trường khác ngoài urlrepeated_nested_json tất cả các trường này đều phải được chuyển qua UDF. Khi tôi làm việc với các bảng có khoảng 50 gb, mọi thứ đều ổn. Nhưng khi tôi áp dụng UDF và truy vấn vào các bảng có 500-1000 gb, tôi nhận được một Lỗi Máy chủ Nội bộ từ BQ.

Cuối cùng, tôi chỉ cần tất cả dữ liệu ở định dạng JSON phân tách dòng mới trong GCS. Như một nỗ lực mương cuối cùng tôi đã cố gắng nối tất cả các lĩnh vực vào một chuỗi JSON (vì vậy mà tôi chỉ có 1 cột) với hy vọng rằng tôi có thể xuất nó dưới dạng CSV và có những gì tôi cần. Tuy nhiên, quá trình xuất thoát khỏi dấu ngoặc kép và thêm dấu nháy kép xung quanh chuỗi JSON. Theo tài liệu BQ về công việc (https://cloud.google.com/bigquery/docs/reference/v2/jobs), có một tài sản configuration.query.tableDefinitions.(key).csvOptions.quote có thể giúp tôi. Nhưng tôi không thể tìm ra cách để nó hoạt động.

Có ai có lời khuyên về cách họ đã xử lý loại tình huống này không?

+0

"Internal Server Error từ BQ" - công việc id xin vui lòng do đó, nhóm có thể điều tra –

+0

@FelipeHoffa sharethis.com:quixotic-spot-526:bquijob_39502947_1535e1c5f59 –

Trả lời

1

Tôi chưa bao giờ phải làm điều này, nhưng bạn sẽ có thể sử dụng flatten, sau đó tham gia, sau đó sử dụng nest để nhận lại các trường lặp lại.

Tài liệu nêu rõ rằng BigQuery luôn làm phẳng kết quả truy vấn, nhưng điều đó có vẻ sai: bạn có thể chọn không có kết quả được làm phẳng nếu bạn đặt bảng đích. Sau đó, bạn có thể xuất bảng đó dưới dạng JSON thành Bộ nhớ.

Xem thêm this answer để biết cách nhận nest để hoạt động.

+1

Một chi tiết phức tạp: Không có cách nào sạch để sử dụng 'NEST' để lấy lại một bản ghi lặp lại - bạn chỉ có thể sử dụng 'NEST' trên các trường lá để lấy lại các bản ghi lặp lại riêng lẻ. Để giải quyết vấn đề này, bạn có thể xem xét việc ghi vào một chuỗi (như đã đề cập trong câu hỏi), bằng cách sử dụng 'NEST' để biến nó trở thành một trường lặp lại, và sau đó sử dụng một UDF để giải nén bản ghi. –

+1

BTW, chúng tôi có những cải tiến đối với phương ngữ SQL của chúng tôi sẽ sớm làm cho tất cả điều này dễ dàng hơn nhiều. Làm theo https://code.google.com/p/google-bigquery/issues/detail?id=448 để nhận thông báo. –

+0

Ngoài ra, 'NEST' phải được sử dụng với' GROUP BY'. Trong trường hợp của tôi, tôi đã không thể pha trộn một lĩnh vực để sử dụng một 'GROUP BY' trên. –

Các vấn đề liên quan