Python BigTable客户端“和”过滤器将返回所有单元格

时间:2019-08-23 18:13:57

标签: bigtable google-cloud-bigtable

我似乎无法弄清楚如何创建正确的过滤器来实现等同于以下MySQL查询的结果。

NAME_V2      FIRST_NAME    MIDDLE_NAME     LAST_NAME
John Smith     John                          Smith
Smith                                        Smith
J O I Smith     J             O I            Smith

用Python BigTable术语,我的第一个想法是使用下面的代码段,但没有返回结果。值得注意的是,当我单独使用任一过滤器时,我会 DO 得到结果,但是当将它们组合使用时,我将不会得到结果。

任何帮助将不胜感激。

select * from TABLE where age >= 10 AND height < 60

2 个答案:

答案 0 :(得分:2)

问题是您正在使用链条。您的age_filt将从age列中输出一个元素,然后将由height_filt 过滤,因为它仅接受height列中的元素。

要模拟AND,您需要做一些更神秘的事情。请原谅伪代码:


    Condition(
      filter=Chain(
        // Return exactly one item for each filter which passes
        Union(
          // Return exactly one item if the age filter passes
          Chain(Column(COL_AGE), ValueRange(>=10), CellsColumnLimit(1)),
          // Return exactly one item if the height filter passes
          Chain(Column(COL_HEIGHT), ValueRange(<60), CellsColumnLimit(1)),
        ),
        // Skip the first element, so we only emit something if both filters pass
        CellsRowOffset(1)),
      true=PassAll())

您可以对可能要执行的任何类型的AND构造使用类似的模式。当然,这是一个巨大的麻烦。在Bigtable中以这种方式工作的原因是过滤器语言被设计为可完全流式传输。换句话说,您的节点可以同时计算一次AND语句,而一次只在内存中保留一个单元,而不用缓冲整个行。条件过滤器是唯一的例外,这也是为什么它们tend to be slow

不相关,但是在对数字进行ValueRangeFilter时,请务必确保使用固定宽度的编码。因此,例如,如果年龄可能为100,则应对年龄进行编码,例如006、052等,以确保过滤器正常工作。

答案 1 :(得分:0)

我相信这里的问题是ColumnQualifierRegexFilter仅返回匹配列中的单元格,而不返回整个行。

这就是为什么需要ConditionalRowFilter的原因。也可以看看: How to get filtered data from Bigtable using Python?

请注意,创建复杂的过滤器链可能会对查询的性能产生负面影响,并且某些过滤器的性能不如其他过滤器。在某些情况下,仅检索大量数据并在客户端进行过滤可以产生更好的性能。另外,如果您发现自己需要构建非常复杂的SQL之类的查询,请考虑使用Cloud Spanner还是BigQuery可能更适合您的用例。