Java - вставлять одну строку за раз в Google Big Query? - PullRequest
0 голосов
/ 08 мая 2018

Я создаю приложение, в котором каждый раз, когда пользователь нажимает на статью, мне нужно собирать данные статьи и пользовательские данные, чтобы рассчитать охват каждой статьи и иметь возможность запускать аналитику по достигнутым данным.

Мое приложение на App Engine.

Когда я проверяю документацию на вставки в BQ, большинство из них указывают на массовые вставки в виде заданий или потоков.

Вопрос : Является ли хорошей практикой вставлять в большой запрос по одной строке каждый раз, когда пользователь инициирует действие? Если да, не могли бы вы указать мне на какой-нибудь Java-код, чтобы эффективно это сделать?

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Упрощенная версия примера Google.

    Map<String, Object> row1Data = new HashMap<>();
    row1Data.put("booleanField", true);
    row1Data.put("stringField", "myString"); 

    Map<String, Object> row2Data = new HashMap<>();
    row2Data.put("booleanField", false);
    row2Data.put("stringField", "myOtherString"); 

    TableId tableId = TableId.of("myDatasetName", "myTableName");
    InsertAllResponse response =
            bigQuery.insertAll(
                    InsertAllRequest.newBuilder(tableId)
                            .addRow("row1Id", row1Data)
                            .addRow("row2Id", row2Data)
                            .build());

    if (response.hasErrors()) {
        // If any of the insertions failed, this lets you inspect the errors
        for (Map.Entry<Long, List<BigQueryError>> entry : response.getInsertErrors().entrySet()) {
            // inspect row error
        }
    }
0 голосов
/ 08 мая 2018

Существуют ограничения на количество заданий загрузки и запросов DML (1000 в день), поэтому вам необходимо использовать потоковые вставки для такого типа приложений. Обратите внимание, что потоковые вставки отличаются от загрузки данных из потока Java.

TableId tableId = TableId.of(datasetName, tableName);
// Values of the row to insert
Map<String, Object> rowContent = new HashMap<>();
rowContent.put("booleanField", true);
// Bytes are passed in base64
rowContent.put("bytesField", "Cg0NDg0="); // 0xA, 0xD, 0xD, 0xE, 0xD in base64
// Records are passed as a map
Map<String, Object> recordsContent = new HashMap<>();
recordsContent.put("stringField", "Hello, World!");
rowContent.put("recordField", recordsContent);
InsertAllResponse response =
    bigquery.insertAll(
        InsertAllRequest.newBuilder(tableId)
            .addRow("rowId", rowContent)
            // More rows can be added in the same RPC by invoking .addRow() on the builder
            .build());
if (response.hasErrors()) {
  // If any of the insertions failed, this lets you inspect the errors
  for (Entry<Long, List<BigQueryError>> entry : response.getInsertErrors().entrySet()) {
    // inspect row error
  }
}

(из примера на https://cloud.google.com/bigquery/streaming-data-into-bigquery#bigquery-stream-data-java)

Обратите внимание, что при неудачной вставке не всегда вызывает исключение. Вы также должны проверить объект ответа на наличие ошибок.

Является ли хорошей практикой вставлять в большой запрос по одной строке каждый раз, когда пользовательское действие инициируется?

Да, довольно типично передавать потоки событий в BigQuery для аналитики. Вы могли бы получить более высокую производительность, если бы вы буферировали несколько событий в одном запросе на вставку в BigQuery, но определенно поддерживается одна строка за раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...