Use CombinePerKey: https://beam.apache.org/documentation/programming-guide/#combine
Python: https://beam.apache.org/documentation/sdks/pydoc/2.5.0/apache_beam.transforms.core.html?highlight=combineperkey#apache_beam.transforms.core.CombinePerKey
Java: https://beam.apache.org/documentation/sdks/javadoc/2.5.0/org/apache/beam/sdk/transforms/Combine.PerKey.html
- Convert P1 & P2 into tuples like this:
code:
P1 = [('H', 'P1'), ('E', 'P1'), ('L', 'P1'), ('L', 'P1'), ('O', 'P1'), ('W', 'P1'), ('O', 'P1'), ('R', 'P1'), ('L', 'P1'), ('D', 'P1')]
P2 = [('W', 'P2'), ('E', 'P2'), ('L', 'P2'), ('C', 'P2'), ('O', 'P2'), ('M', 'P2'), ('E', 'P2')]
Flatten the 2 p-collections together
pass the flattened p-collection into a CombinePerKey, with a CombineFn that marks if a string has in both p1 & p2:
code:
class IsInBoth(apache_beam.core.CombineFn):
def _add_inputs(self, elements, accumulator=None):
accumulator = accumulator or self.create_accumulator()
for obj in elements:
if obj == 'P1':
accumulator['P1'] = True
if obj == 'P2':
accumulator['P2'] = True
return accumulator
def create_accumulator(self):
return {'P1': False, 'P2': False}
def add_input(self, accumulator, element, *args, **kwargs):
return self._add_inputs(elements=[element], accumulator=accumulator)
def add_inputs(self, accumulator, elements, *args, **kwargs):
return self._add_inputs(elements=elements, accumulator=accumulator)
def merge_accumulators(self, accumulators, *args, **kwargs):
return {
'P1': any([i['P1'] for i in accumulators]),
'P2': any([i['P2'] for i in accumulators])}
def extract_output(self, accumulator, *args, **kwargs):
return accumulator
- filter out the results from
CombinePerKey that have {'P1': True, 'P2': True}