Bigtable CellsColumnLimitFilter 和 ValueRangeFilter 未按预期工作

Bigtable CellsColumnLimitFilter and ValueRangeFilter not working as intended

我是 Bigtable 的新手,我一直在测试基于此文档的过滤功能。 https://cloud.google.com/bigtable/docs/using-filters

我已经在 testcsvbigtablefilters.py 下的这个 repo 中尝试过这个,但我遇到了一些问题。作为记录,我正在我本地机器上的 Bigtable 模拟器上测试这个 https://github.com/limjix/GoogleCloudBigDataTest

我在使用 2 个过滤器时遇到一些问题:

  1. CellsColumnLimitFilter(第 100-110 行,取消注释试试) 这个过滤器似乎不起作用。我有一个 table 的 3 列,但是当我放置 CellsColumnLimitFilter(1) 或 CellsColumnLimitFilter(2) 时,我仍然得到所有 3 列?
     rows = table.read_rows(filter_=row_filters.CellsColumnLimitFilter(10))
     for row in rows:
         print_row(row)
  1. ValueRangeFilter(第 172-183 行) 此过滤器不起作用,因为例如我的第一列的值在 10000 到 14000 左右。 当我将起始值设置为 10,000 到 14,000 时,什么也没有出现。 当我把 0 放到 3 时,10k 到 14k 的值开始出现。这毫无意义,过滤器似乎根本不起作用
    rows = table.read_rows(
        filter_=row_filters.ValueRangeFilter(start_value=b'0',end_value=b'3'))

    for row in rows:
        print_row(row)

另外,我想问一下,如何查询被覆盖的单元格?我知道bigtable保存了一段时间内细胞的变异。如何查询和筛选该单元格的特定时间?

任何帮助将不胜感激,其他地方没有太多教程或文档,所以我希望社区能提供帮助。

谢谢!

嘿 limjix,感谢您提出问题!刚刚介绍了 Bigtable 过滤文档,所以像这样的问题可以帮助我们改进它。

  1. CellsColumnLimitFilter

CellsColumnLimitFilter 限制了每列中包含在输出行中的单元格数。在文档中它被列为 cells per column filter,所以我可以看出这个函数名称有点混乱。

如果只有一行包含几列,并且这些值只有一个单元格或一个版本,那么 CellsColumnLimitFilter 会 return 所有这些。如果您只想接收列的一个数据,您可以使用 CellsRowLimitFilter 过滤每行的单元格。或者您可以使用任何列限定符过滤器指定特定列。

  1. ValueRangeFilter

我做了一些调查,我相信我知道你的问题是什么,但我不是 100%。如果您需要,我很乐意与您一起进一步解决问题。

您似乎直接从 CSV 文件设置单元格值:

bigtablerow.set_cell(column_family_id,
             "column1",
             #str(float(csvrow[20])+i),
             csvrow[20],
             timestamp=datetime.datetime.utcnow())

这适用于字符串,但如果您将单元格值设置为数字,python 客户端会将其视为可递增的值并将其编码为 64 位 big-endian 签名整数,将无法与您拥有的 b'10000' 进行比较。

例如,此代码不会 return 任何行:

client = bigtable.Client(project=project_id, admin=True)
instance = client.instance(instance_id)
table = instance.table(table_id)

rows = []
for i in range(10):
    row_key = 'test_num{}'.format(i).encode()
    row = table.direct_row(row_key)
    row.set_cell("cf".encode(),
                 "col".encode(),
                 random.randint(10000, 14000)
                 )
    rows.append(row)
table.mutate_rows(rows)


rows = table.read_rows(
    filter_=row_filters.ValueRangeFilter(start_value=b'10000',
                                         end_value=b'14000'))
for row in rows:
    print(row)

但是当我将整数转换为字符串时,我得到了所有行

    row.set_cell("cf".encode(),
                 "col".encode(),
                 str(random.randint(10000, 14000))
                 )
    rows.append(row)

我建议使用 CBT 工具来检查数据的外观。例如,当我执行 cbt read 时,第一行如下所示:

test_num0
  cf:col                                   @ 2020/09/20-22:24:43.835000
    "\x00\x00\x00\x00\x00\x003\xd1"
----------------------------------------
test_num1
  cf:col                                   @ 2020/09/20-22:24:43.835000
    "\x00\x00\x00\x00\x00\x001t"

而字符串看起来像这样(它们有两个值,因为我实际上使用了相同的行键,但你应该明白这一点):

test_num0
  cf:col                                   @ 2020/09/20-22:36:12.075000
    "11510"
  cf:col                                   @ 2020/09/20-22:24:43.835000
    "\x00\x00\x00\x00\x00\x003\xd1"
----------------------------------------
test_num1
  cf:col                                   @ 2020/09/20-22:36:12.075000
    "12048"
  cf:col                                   @ 2020/09/20-22:24:43.835000
    "\x00\x00\x00\x00\x00\x001t"
  1. 正在查询已被覆盖的单元格

这类似于您在第一个示例中尝试执行的操作。对于已被覆盖的单元格,您正在寻找围绕单元格时间戳 (TimestampRangeFilter) 或每列单元格数(再次 CellsColumnLimitFilter)的过滤器。