当联接不适用时,根据其他列表筛选列表

时间:2013-07-30 20:10:08

标签: apache-pig

假设有一个Intervals列表和一个Points列表,它来自两个不同的查询计划。

假设Intervals列表的签名是:

Intervals : { (start:int, stop:int) }
因此,这是夫妻名单。

很明显,Points是一个单身人士名单:

Points: { (coordinate:int) }

我想要做的是从Points集中检索至​​少在Intervals集合的一个时间间隔内包含的所有点。

我做了什么,实施这个琐碎的计划:

cp = CROSS Points, Intervals;
cp_filtered = FILTER cp BY start < coordinate and coordinate < stop;
filtered_point = FOREACH cp_filtered GENERATE coordinate;

当然,如果列表的基数很高,那么交叉产品就不是一个好选择。

我想知道PigLatin通常如何解决这样的问题。你能帮帮我吗?

1 个答案:

答案 0 :(得分:1)

您可以使用Python UDF将时间间隔转换为范围,然后JOIN使用范围:

myudf.py

#!/usr/bin/python

@outputSchema('expanded: {(num:int)}')
def expand(start, end):
    return [ (x) for x in range(start + 1, end) ]

myscript.pig

REGISTER 'myudf.py' using jython as myudf ;   

-- expand creates a bag of all numbers in the range 
B = FOREACH Intervals GENERATE FLATTEN(myudf.expand(start, end)) ;

-- Maybe do DISTINCT on B to speed up the JOIN?

C = JOIN B by num, Points by coordinate ;

我不确定这是否是您最快的选择,但对于较大的数据集,它应该比CROSS快得多。