Перебирать версии ячеек в строке BigTable - PullRequest
1 голос
/ 14 января 2020

У меня есть строка с несколькими версиями конкретной ячейки. Я хочу получить и перебрать все существующие версии этой ячейки . Что-то вроде:

for _, cellVersion := range row["ColumnFamily"]["ColumnQualifier"]{
   // (...)
}

Я пытался использовать функцию ReadRow, но она возвращает map[string][]ReadItem, который, по-видимому, является одномерным массивом ячеек.

row, err := table.ReadRow(ctx, rowKey)
row["MyColumnFamily"] // -> array of unidimensional cells

Ответы [ 2 ]

1 голос
/ 18 января 2020

Причиной моего вопроса стал тот факт, что модель данных BigTable поддерживает несколько версий каждой ячейки. Упрощенно: каждая ячейка - это многомерный массив различных версий одного и того же фрагмента данных.

BigTable data model

В Python SDK это реализовано в очень простой форме: каждая ячейка представлена ​​в виде списка элементов (список возможных версий).

>>> row = table.read_row(ROW_KEY)
>>> data = row.to_dict()
>>> cell = data[<COLUMN_FAMILY:COLUMN_QUALIFIER>]
[<Cell value=b'bla1' timestamp=2020-01-16 21:45:39.921000>, <Cell value=b'bla2' timestamp=2020-01-16 21:57:31>...]

Однако в Golang SDK все версии всех ячеек находятся в тот же массив. Следовательно, если вам нужен массив со всеми версиями одной и той же ячейки, вам нужно сгруппировать его вручную.

row, _ := r.table.ReadRow(ctx, ROW_KEY)
columns, ok := row[<COLUMN_FAMILY>]

values := make(map[string][]bigtable.ReadItem, 0)

for _, cell := range columns {
    _, ok := values[cell.Column]
    if !ok {
        values[cell.Column] = make([]bigtable.ReadItem, 0)
    }

    values[cell.Column] = append(values[cell.Column], cell)
 }

Теперь мы можем получить доступ к списку различных версий одной и той же ячейки:

cell := values[<COLUMN_FAMILY:COLUMN_QUALIFIER>]
for _, cellVersion := range cell{
    ...
}
1 голос
/ 14 января 2020

Вы должны иметь возможность выбрать строку для указанного столбца c и затем выполнить итерацию по всем результатам:

rowkey := "YOUR_KEY"
row, err := tbl.ReadRow(ctx, rowkey, bigtable.RowFilter(bigtable.ColumnFilter("ColumnQualifier")))
if err != nil {
    log.Fatalf("Could not read row with key %s: %v", rowkey, err)
}

printRow(w, row)

func printRow(w io.Writer, row bigtable.Row) {
    fmt.Fprintf(w, "Reading data for %s:\n", row.Key())
    for columnFamily, cols := range row {
        fmt.Fprintf(w, "Column Family %s\n", columnFamily)
        for _, col := range cols {
            qualifier := col.Column[strings.IndexByte(col.Column, ':')+1:]
            fmt.Fprintf(w, "\t%s: %s @%d\n", qualifier, col.Value, col.Timestamp)
        }
    }
    fmt.Fprintln(w)
}
...