{"id":601911,"date":"2019-02-21T11:10:19","date_gmt":"2019-02-21T10:10:19","guid":{"rendered":"https:\/\/www.devoteam.com\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/"},"modified":"2019-02-21T11:10:19","modified_gmt":"2019-02-21T10:10:19","slug":"implementing-a-left-join-in-google-dataflow-apache-beam","status":"publish","type":"expert-view","link":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/","title":{"rendered":"Implementing a left join in Google Dataflow (Apache Beam)"},"content":{"rendered":"<div class=\"block-fullwidth-dark\">\n<pre style=\"text-align: center\"><strong>NOTE: The python example code for this technical \n<\/strong><strong>blog can be found in this GitHub repo:<\/strong><\/pre>\n<div class=\"row-more clearfix\"><a class=\"bt-more\" href=\"https:\/\/github.com\/HocLengChung\/Apache-Beam-Dataflow-for-public\/blob\/master\/leftjoin-blogexample.py\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a><\/div>\n<\/div>\n<p><span style=\"font-weight: 400\">Consider the following situation; you have some data loaded into Apache Beam which you need to process. You have some value in the source data which you want to use to find a unique row in a BigQuery table. Consider the following source data.<\/span><\/p>\n<table style=\"width: 100%\">\n<tbody>\n<tr>\n<td style=\"width: 13%\"><b>Row UUID<\/b><\/td>\n<td style=\"width: 19%\"><b>Country<\/b><\/td>\n<td style=\"width: 12.3321%\"><b>Year<\/b><\/td>\n<td style=\"width: 52.6679%\"><b>Cheese consumption per capita per year (kg)<\/b><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13%\"><span style=\"font-weight: 400\">1<\/span><\/td>\n<td style=\"width: 19%\"><span style=\"font-weight: 400\">The Netherlands<\/span><\/td>\n<td style=\"width: 12.3321%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 52.6679%\"><span style=\"font-weight: 400\">19.4<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13%\"><span style=\"font-weight: 400\">2<\/span><\/td>\n<td style=\"width: 19%\"><span style=\"font-weight: 400\">The Netherlands<\/span><\/td>\n<td style=\"width: 12.3321%\"><span style=\"font-weight: 400\">2012<\/span><\/td>\n<td style=\"width: 52.6679%\"><span style=\"font-weight: 400\">20.1<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13%\"><span style=\"font-weight: 400\">3<\/span><\/td>\n<td style=\"width: 19%\"><span style=\"font-weight: 400\">France<\/span><\/td>\n<td style=\"width: 12.3321%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 52.6679%\"><span style=\"font-weight: 400\">26.3<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13%\"><span style=\"font-weight: 400\">4<\/span><\/td>\n<td style=\"width: 19%\"><span style=\"font-weight: 400\">China<\/span><\/td>\n<td style=\"width: 12.3321%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 52.6679%\"><span style=\"font-weight: 400\">0.1<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><i>Table 1. Source data<\/i><\/p>\n<h2><span style=\"font-weight: 400\">The Challenge<\/span><\/h2>\n<p><span style=\"font-weight: 400\">We want to look up in which continent the countries described in the table above reside for each row. As an example we have the following table from some data source (e.g. BigQuery, json etc.):<\/span><\/p>\n<table style=\"width: 393px\">\n<tbody>\n<tr>\n<td style=\"width: 161.4px\"><b>Country<\/b><\/td>\n<td style=\"width: 225.6px\"><b>Continent<\/b><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 161.4px\"><span style=\"font-weight: 400\">The Netherlands<\/span><\/td>\n<td style=\"width: 225.6px\"><span style=\"font-weight: 400\">Europe<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 161.4px\"><span style=\"font-weight: 400\">China<\/span><\/td>\n<td style=\"width: 225.6px\"><span style=\"font-weight: 400\">Asia<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 161.4px\"><span style=\"font-weight: 400\">France<\/span><\/td>\n<td style=\"width: 225.6px\"><span style=\"font-weight: 400\">Europe<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 161.4px\"><span style=\"font-weight: 400\">Brazil<\/span><\/td>\n<td style=\"width: 225.6px\"><span style=\"font-weight: 400\">South America<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><i>Table 2. Join Data<\/i><\/p>\n<p><span style=\"font-weight: 400\">We need to left join on country to find the correct continent. In SQL, a left join is a command to join two tables with a common column. The SQL command would be:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>SELECT Row UUID, Country, Year, Cheese consumption per capita per year (kg)\nFROM table1\nLEFT JOIN table2 ON table1.Country = table2.Country;<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">We want to join the first table with the second table on the Country column. This would result in following joined table:<\/span><\/p>\n<table style=\"width: 100%\">\n<tbody>\n<tr>\n<td style=\"width: 12%\"><b>Row UUID<\/b><\/td>\n<td style=\"width: 18%\"><b>Country<\/b><\/td>\n<td style=\"width: 11.8137%\"><b>Year<\/b><\/td>\n<td style=\"width: 43.1863%\"><b>Cheese consumption per capita per year (kg)<\/b><\/td>\n<td style=\"width: 11%\"><b>Continent<\/b><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 12%\"><span style=\"font-weight: 400\">1<\/span><\/td>\n<td style=\"width: 18%\"><span style=\"font-weight: 400\">The Netherlands<\/span><\/td>\n<td style=\"width: 11.8137%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 43.1863%\"><span style=\"font-weight: 400\">19.4<\/span><\/td>\n<td style=\"width: 11%\"><span style=\"font-weight: 400\">Europe<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 12%\"><span style=\"font-weight: 400\">2<\/span><\/td>\n<td style=\"width: 18%\"><span style=\"font-weight: 400\">The Netherlands<\/span><\/td>\n<td style=\"width: 11.8137%\"><span style=\"font-weight: 400\">2012<\/span><\/td>\n<td style=\"width: 43.1863%\"><span style=\"font-weight: 400\">20.1<\/span><\/td>\n<td style=\"width: 11%\"><span style=\"font-weight: 400\">Europe<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 12%\"><span style=\"font-weight: 400\">3<\/span><\/td>\n<td style=\"width: 18%\"><span style=\"font-weight: 400\">France<\/span><\/td>\n<td style=\"width: 11.8137%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 43.1863%\"><span style=\"font-weight: 400\">26.3<\/span><\/td>\n<td style=\"width: 11%\"><span style=\"font-weight: 400\">Europe<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 12%\"><span style=\"font-weight: 400\">4<\/span><\/td>\n<td style=\"width: 18%\"><span style=\"font-weight: 400\">China<\/span><\/td>\n<td style=\"width: 11.8137%\"><span style=\"font-weight: 400\">2011<\/span><\/td>\n<td style=\"width: 43.1863%\"><span style=\"font-weight: 400\">0.1<\/span><\/td>\n<td style=\"width: 11%\"><span style=\"font-weight: 400\">Asia<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The left join is a build-in function in SQL and is very useful to match records from 1 table with another in relational databases. In Apache Beam however there is no left join implemented natively. There is however a CoGroupByKey PTransform that can merge two data sources together by a common key.<\/p>\n<h2><span style=\"font-weight: 400\">How to implement a left join using the python version of Apache Beam<\/span><\/h2>\n<p><span style=\"font-weight: 400\">The overall workflow of the left join is presented in the dataflow diagram presented in Figure 1.\u00a0<\/span><\/p>\n<p><a href=\"https:\/\/nl.devoteam.com\/wp-content\/uploads\/sites\/15\/2019\/02\/hcl-technical-blog-google-cloud-platform-devoteam.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-72901 size-large\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/hcl-technical-blog-google-cloud-platform-devoteam-tt-width-300-height-304-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.png\" alt=\"hcl-technical-blog-google-cloud-platform-devoteam\" width=\"300\" height=\"304\" \/><\/a><\/p>\n<p style=\"text-align: center\"><i>Figure 1. Overall Dataflow Diagram<\/i><b><i><br \/>\n<\/i><\/b><i>(Click to enlarge)<\/i><\/p>\n<p><span style=\"font-weight: 400\">In a production environment you would typically have data in some file format (e.g. csv, json, txt) which you have read using for example the build-in ReadFromText module of Apache Beam IO and do some processing using DoFn\u2019s to format it as a pcollection of dictionaries. <\/span><\/p>\n<h2><span style=\"font-weight: 400\">CoGroupByKey explained<\/span><\/h2>\n<p><span style=\"font-weight: 400\">In order to use the CoGroupByKey PTransform, we need to format the read data as common (key, value) tuples. The read data from 2 or more sources are grouped together by the common key. Figure 2 shows what the CoGroupByKey looks like in python syntax, where we have 2 element tuples to be cogrouped. Each 2-element tuple must contain a key to be grouped. The first element of the tuple is the key and the second element of the tuple is the object you want to group. It can be any serializable object<\/span><span style=\"font-weight: 400\">. The grouped tuple contains (for every unique key) one 2-element tuple where the second element is a dictionary where the keys are the names of the data sources and the values are a list of all the second elements of the set of all data source tuples you want to cogroup.<\/span><\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-72911\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/hcl-technical-blog-google-cloud-platform-2-devoteam-tt-width-635-height-405-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.png\" alt=\"hcl-technical-blog-google-cloud-platform-2-devoteam\" \/><i>Figure 2. CogroupByKey Diagram<\/i><\/p>\n<p><span style=\"font-weight: 400\">Apache Beam&#8217;s built-in <\/span><a href=\"https:\/\/beam.apache.org\/documentation\/programming-guide\/#cogroupbykey\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400\">CoGroupByKey<\/span><\/a><span style=\"font-weight: 400\"> core Beam transform forms the basis of a left join. The objects we want to cogroup are in case of a LeftJoin dictionaries. Example source data tuples:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>('The Netherlands', {'Country': 'The Netherlands', 'Year': '2011','Cheese consumption \nper capita per year (kg)': '19.4'})<\/pre>\n<pre>('The Netherlands', {'Country': 'The Netherlands', 'Year': '2012','Cheese consumption \nper capita per year (kg)': '20.1'})<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">Example join data tuple:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>('The Netherlands', {'Country': 'The Netherlands', 'Continent': 'Europe'})<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">Example grouped tuple:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>('The Netherlands', {'source_data': [{'Country': 'The Netherlands', 'Cheese consumption \nper capita per year (kg)': '20.1', 'Year': '2012'}, {'Country': 'The Netherlands', \n'Cheese consumption per capita per year (kg)': '19.4', 'Year': '2011'}], 'join_data': \n[{'Country': 'The Netherlands', 'Continent': 'Europe'}]})<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">We still need to unnest the CoGroupBykey output to get the original source data. So our grouped tuple has to become like the following:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>{'Country': 'The Netherlands', 'Cheese consumption per capita per year (kg)': \n'19.4', 'Continent': 'Europe', 'Year': '2011'}<\/pre>\n<pre>{'Country': 'The Netherlands', 'Cheese consumption per capita per year (kg)': \n'20.1', 'Continent': 'Europe', 'Year': '2012'}<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\"> We will explain how to implement the entire left join process in Apache Beam.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">How to implement Left Join using CoGroupByKey<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/h2>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-72921\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/hcl-technical-blog-google-cloud-platform-3-devoteam-tt-width-1184-height-1305-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.png\" alt=\"hcl-technical-blog-google-cloud-platform-3-devoteam\" \/><\/p>\n<p style=\"text-align: center\"><i>Figure 3. Overall Join Dataflow Diagram<\/i><\/p>\n<p><span style=\"font-weight: 400\">The Dataflow diagram of the join process is presented in Figure 3. The join process has 4 processing steps consisting of steps 1.1, 1.2, 2.0 and 3.0. Steps 1.1 and 1.2 run in parallel and steps 2.0 and 3.0 run after each other. We are now going to walkthrough the transformation process of the dataflow diagram in Figure 3. At step 0.1 and 0.2 we have (for illustration purposes) the source_data and join_data pcollection. For the purpose of our example implementation we generate these read elements ourselves. The following code creates the example dictionaries in Apache Beam, puts them into a pipelines_dictionary containing the source data and join data pipeline names and their respective pcollections and performs a Left Join.<\/span><\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-73591\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/google-cloud-platform-technical-blog-left-join-tables-devoteam-1-tt-width-574-height-989-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.jpg\" alt=\"google-cloud-platform-technical-blog-left-join-tables-devoteam-1\" \/><\/p>\n<p style=\"text-align: center\"><em>The code above can be found as part of the example code on the\u00a0<a href=\"https:\/\/github.com\/HocLengChung\/Apache-Beam-Dataflow-for-public\/blob\/master\/leftjoin-blogexample.py\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a><\/em><\/p>\n<p><span style=\"font-weight: 400\">The LeftJoin is implemented as a composite PTransform. The composite PTransform takes as input a pipelines_dictionary containing the source_pipeline_name, source_data pcollection, join_pipeline_name and join_data pcollection.<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-73601\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/google-cloud-platform-technical-blog-left-join-tables-devoteam-2-tt-width-602-height-53-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.jpg\" alt=\"google-cloud-platform-technical-blog-left-join-tables-devoteam-2\" \/><\/p>\n<p style=\"text-align: center\"><em>The code above can be found as part of the example code on the <a href=\"https:\/\/github.com\/HocLengChung\/Apache-Beam-Dataflow-for-public\/blob\/master\/leftjoin-blogexample.py\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a><\/em><\/p>\n<p><span style=\"font-weight: 400\">It also needs source_pipeline_name, source_data, \u00a0join_pipeline_name, join_data and common_key as constructor variables. An example walkthrough of the transformations that happen with the data is as follows.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For example:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>{'Country': 'The Netherlands', 'Year': '2011',\n 'Cheese consumption per capita per year (kg)': '19.4'}<\/pre>\n<pre>{'Country': 'The Netherlands', 'Year': '2012', \n'Cheese consumption per capita per year (kg)': '20.1'}<\/pre>\n<pre>{'Country': 'France', 'Year': '2011', \n'Cheese consumption per capita per year (kg)': '26.3'}<\/pre>\n<pre>{'Country': 'China', 'Year': '2012',\n'Cheese consumption per capita per year (kg)': '0.1'}<\/pre>\n<\/div>\n<p>and<\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>{'Country': 'The Netherlands', 'Continent': 'Europe'}\n{'Country': 'China', 'Continent': 'Asia'}\n{'Country': 'USA', 'Continent': 'North America'}\n{'Country': 'Brazil', 'Continent': 'South America'}<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">becomes<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>('Brazil', {'source_data': [], 'join_data': [{'Country': 'Brazil', \n'Continent': 'South America'}]})<\/pre>\n<pre>('USA', {'source_data': [], 'join_data': [{'Country': 'USA', \n'Continent': 'North America'}]})<\/pre>\n<pre>('The Netherlands', {'source_data': [{'Country': 'The Netherlands', \n'Cheese consumption per capita per year (kg)': '20.1', 'Year': '2012'}, \n{'Country': 'The Netherlands', 'Cheese consumption per capita \nper year (kg)': '19.4', 'Year': '2011'}], 'join_data': [{'Country': \n'The Netherlands', 'Continent': 'Europe'}]})<\/pre>\n<pre>('China', {'source_data': [{'Country': 'China', \n'Cheese consumption per capita per year (kg)': '0.1', \n'Year': '2011'}], 'join_data': [{'Country': 'China', \n'Continent': 'Asia'}]})<\/pre>\n<pre>('France', {'source_data': [{'Country': 'France', \n'Cheese consumption per capita per year (kg)': '26.3', \n'Year': '2011'}], 'join_data': []})<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">From here onwards we unnests the source data dictionaries and update them with the matched joined data dictionary. We then emit the updated source data dictionaries. The output will then be:<\/span><\/p>\n<div class=\"block-fullwidth-dark\">\n<pre>{'Country': 'The Netherlands', 'Year': '2011', \n'Cheese consumption per capita per year (kg)': '19.4', 'Continent': 'Europe'}<\/pre>\n<pre>{'Country': 'The Netherlands', 'Year': '2012', \n'Cheese consumption per capita per year (kg)': '20.1', 'Continent': 'Europe'}<\/pre>\n<pre>{'Country': 'France', 'Year': '2011', \n'Cheese consumption per capita per year (kg)': '26.3'}<\/pre>\n<pre>{'Country': 'China', 'Year': '2011',\n'Cheese consumption per capita per year (kg)': '0.1', 'Continent': 'Asia'}<\/pre>\n<\/div>\n<p><span style=\"font-weight: 400\">The PTransform code uses 2 classes, namely the LeftJoin Ptransform class and the UnnestCoGrouped DoFn class. The LeftJoin is a Composite PTransform that uses dictionary comprehension and Map to format the source and join data as suitable cogroupby tuples. It then uses the built-in CoGroupByKey PTransform to group them together by common_key. The last part is to unnest the grouped dictionaries and emit the updated dictionaries which is done using the UnnestCogrouped DoFn.<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-73611\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/google-cloud-platform-technical-blog-left-join-tables-devoteam-3-tt-width-602-height-709-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.jpg\" alt=\"google-cloud-platform-technical-blog-left-join-tables-devoteam-3\" \/><\/p>\n<p style=\"text-align: center\"><em>The code above can be found as part of the example code on the <a href=\"https:\/\/github.com\/HocLengChung\/Apache-Beam-Dataflow-for-public\/blob\/master\/leftjoin-blogexample.py\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a><\/em><\/p>\n<p><span style=\"font-size: 0.875rem;background-color: #ffffff\">The full example code block to run this example is given below:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-73621\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/google-cloud-platform-technical-blog-left-join-tables-devoteam-4a-tt-width-602-height-747-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.jpg\" alt=\"google-cloud-platform-technical-blog-left-join-tables-devoteam-4a\" \/><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-73631\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/google-cloud-platform-technical-blog-left-join-tables-devoteam-4b-tt-width-602-height-695-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.jpg\" alt=\"google-cloud-platform-technical-blog-left-join-tables-devoteam-4b\" \/><\/p>\n<p style=\"text-align: center\"><em>The code above can be found as part of the example code on the <a href=\"https:\/\/github.com\/HocLengChung\/Apache-Beam-Dataflow-for-public\/blob\/master\/leftjoin-blogexample.py\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a><\/em><\/p>\n<p><span style=\"font-size: 0.875rem;background-color: #ffffff\">If you run this example you would have the following Graph in Dataflow:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-72931\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/hcl-technical-blog-google-cloud-platform-4-devoteam-tt-width-416-height-183-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.png\" alt=\"hcl-technical-blog-google-cloud-platform-4-devoteam\" \/><\/p>\n<p><span style=\"font-weight: 400\">Which can be magnified by clicking on the down arrow next to the Left Join node:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-72951\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/hcl-technical-blog-google-cloud-platform-5-devoteam-tt-width-466-height-440-fill-0-crop-0-bgcolor-eeeeee-except_gif-1.png\" alt=\"hcl-technical-blog-google-cloud-platform-5-devoteam\" \/><\/p>\n<p><span style=\"font-weight: 400\">Exposing the nested logic of the implemented Leftjoin PTransform.<\/span><\/p>\n<p><span style=\"font-weight: 400\">If you want to use the implemented LeftJoin, you would need the LeftJoin PTransform class and the UnnestCoGrouped DoFn class. Use the full code as an example guide to use the LeftJoin PTransform. This completes the walkthrough of implementing a LeftJoin in the python version of Apache Beam. <\/span><\/p>\n<h2><span style=\"font-weight: 400\">Conclusion<\/span><\/h2>\n<p><span style=\"font-weight: 400\">In short, this article explained how to implement a leftjoin in the python version of Apache Beam. The user can use the provided example code as a guide to implement leftjoin in their own Apache Beam workflows. If you want to learn more about Apache Beam, <\/span><span style=\"font-weight: 400\"><a href=\"https:\/\/beam.apache.org\/documentation\/\" target=\"_blank\" rel=\"noopener noreferrer\">click here to get all the Apache Beam resources<\/a>.<\/span><\/p>\n<div class=\"row-more clearfix\"><\/div>\n<h3>Related Google Cloud Technical blog-posts<\/h3>\n<ul>\n<li><a href=\"https:\/\/nl.devoteam.com\/expert-view\/creating-a-master-orchestrator-to-handle-complex-google-cloud-composer-jobs\/\">Creating a master orchestrator to handle complex Google Cloud Composer jobs<\/a><\/li>\n<li><a href=\"https:\/\/nl.devoteam.com\/expert-view\/creating-complex-orchestrations-with-google-cl-composer-using-sub_controllers\/\">Creating complex orchestrations with Google Cloud Composer using sub_controllers<\/a><\/li>\n<li><a href=\"https:\/\/nl.devoteam.com\/expert-view\/google-cloud-infrastructure-as-code-with-terraform\/\">Google Cloud: Infrastructure as Code with Terraform<\/a><\/li>\n<li><a href=\"https:\/\/nl.devoteam.com\/expert-view\/creating-anonymized-primary-keys-for-google-bigquery\/\">Creating anonymized Primary keys for Google BigQuery<\/a><\/li>\n<\/ul>\n<div class=\"block-fullwidth-dark\">\n<h2>Join our open &amp; innovative culture<\/h2>\n<p>Open, accessible and ambitious are the keywords of our organizational culture. We encourage making mistakes, we strive to do better every day and love to have fun. Doing work you love with brilliant people is what it&#8217;s all about.<\/p>\n<div class=\"row-more clearfix\"><a class=\"bt-more\" href=\"https:\/\/nl.devoteam.com\/working-at-devoteam\/\" target=\"_blank\" rel=\"noopener noreferrer\">Discover more<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>NOTE: The python example code for this technical blog can be found in this GitHub repo: GitHub repo Consider the following situation; you have some data loaded into Apache Beam which you need to process. You have some value in the source data which you want to use to find a unique row in a [&hellip;]<\/p>\n","protected":false},"featured_media":347873,"template":"","categories":[],"tags":[2297,1829,2717],"industry":[],"class_list":["post-601911","expert-view","type-expert-view","status-publish","has-post-thumbnail","hentry","tag-data-en-nl","tag-google-cloud-en-nl","tag-netherlands-en-nl"],"acf":[],"cards":"\n\t<div class=\"single-post-card\">\n\n\t\t<figure class=\"wp-block-post-featured-image\"><a href=\"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/\" target=\"_self\" ><img width=\"1920\" height=\"600\" src=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg\" class=\"attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"Implementing a left join in Google Dataflow (Apache Beam)\" style=\"aspect-ratio:4\/3;width:100%;object-fit:cover;\" decoding=\"async\" loading=\"lazy\" srcset=\"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg 1920w, https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-300x94.jpg 300w, https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-1024x320.jpg 1024w, https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-768x240.jpg 768w, https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-1536x480.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n\n\t\t\n\t\t<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-43282307 wp-block-group-is-layout-flex\">\n\t<p style=\"font-style:normal;font-weight:700\" class=\"has-link-color wp-elements-1 wp-block-lp-post-type has-text-color has-primary-color has-small-font-size\">Expert View<\/p>\n\n\t\t\n\t\t<h3 style=\"font-style:normal;font-weight:400\" class=\"wp-block-post-title has-base-font-size\"><a href=\"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/\" target=\"_self\" >Implementing a left join in Google Dataflow (Apache Beam)<\/a><\/h3><\/div>\n\t\t\n\t<\/div>\n\n","yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.4 (Yoast SEO v28.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Implementing a left join in Google Dataflow (Apache Beam) | Devoteam<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Implementing a left join in Google Dataflow (Apache Beam)\" \/>\n<meta property=\"og:description\" content=\"NOTE: The python example code for this technical blog can be found in this GitHub repo: GitHub repo Consider the following situation; you have some data loaded into Apache Beam which you need to process. You have some value in the source data which you want to use to find a unique row in a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/\" \/>\n<meta property=\"og:site_name\" content=\"Devoteam\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/\",\"url\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/\",\"name\":\"Implementing a left join in Google Dataflow (Apache Beam) | Devoteam\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/background-devoteam-blog.jpg\",\"datePublished\":\"2019-02-21T10:10:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/#breadcrumb\"},\"inLanguage\":\"en-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-NL\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/#primaryimage\",\"url\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/background-devoteam-blog.jpg\",\"contentUrl\":\"https:\\\/\\\/devoteam.info\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/background-devoteam-blog.jpg\",\"width\":1920,\"height\":600},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/implementing-a-left-join-in-google-dataflow-apache-beam\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Expert View\",\"item\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/expert-view\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Implementing a left join in Google Dataflow (Apache Beam)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/#website\",\"url\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/\",\"name\":\"Devoteam\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/devoteam.info\\\/en-nl\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-NL\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Implementing a left join in Google Dataflow (Apache Beam) | Devoteam","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/","og_locale":"en_US","og_type":"article","og_title":"Implementing a left join in Google Dataflow (Apache Beam)","og_description":"NOTE: The python example code for this technical blog can be found in this GitHub repo: GitHub repo Consider the following situation; you have some data loaded into Apache Beam which you need to process. You have some value in the source data which you want to use to find a unique row in a [&hellip;]","og_url":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/","og_site_name":"Devoteam","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/","url":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/","name":"Implementing a left join in Google Dataflow (Apache Beam) | Devoteam","isPartOf":{"@id":"https:\/\/devoteam.info\/en-nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/#primaryimage"},"image":{"@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/#primaryimage"},"thumbnailUrl":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg","datePublished":"2019-02-21T10:10:19+00:00","breadcrumb":{"@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/#breadcrumb"},"inLanguage":"en-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/"]}]},{"@type":"ImageObject","inLanguage":"en-NL","@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/#primaryimage","url":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg","contentUrl":"https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg","width":1920,"height":600},{"@type":"BreadcrumbList","@id":"https:\/\/devoteam.info\/en-nl\/expert-view\/implementing-a-left-join-in-google-dataflow-apache-beam\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devoteam.info\/en-nl\/"},{"@type":"ListItem","position":2,"name":"Expert View","item":"https:\/\/devoteam.info\/en-nl\/expert-view\/"},{"@type":"ListItem","position":3,"name":"Implementing a left join in Google Dataflow (Apache Beam)"}]},{"@type":"WebSite","@id":"https:\/\/devoteam.info\/en-nl\/#website","url":"https:\/\/devoteam.info\/en-nl\/","name":"Devoteam","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devoteam.info\/en-nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-NL"}]}},"uagb_featured_image_src":{"full":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg",1920,600,false],"thumbnail":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-150x150.jpg",150,150,true],"medium":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-300x94.jpg",300,94,true],"medium_large":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-768x240.jpg",768,240,true],"large":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-1024x320.jpg",1024,320,true],"1536x1536":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog-1536x480.jpg",1536,480,true],"2048x2048":["https:\/\/devoteam.info\/wp-content\/uploads\/2024\/12\/background-devoteam-blog.jpg",1920,600,false]},"uagb_author_info":{"display_name":"lea.mitteaux","author_link":"https:\/\/devoteam.info\/en-nl\/author\/"},"uagb_comment_info":0,"uagb_excerpt":"NOTE: The python example code for this technical blog can be found in this GitHub repo: GitHub repo Consider the following situation; you have some data loaded into Apache Beam which you need to process. You have some value in the source data which you want to use to find a unique row in a&hellip;","_links":{"self":[{"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/expert-view\/601911","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/expert-view"}],"about":[{"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/types\/expert-view"}],"version-history":[{"count":0,"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/expert-view\/601911\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/media\/347873"}],"wp:attachment":[{"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/media?parent=601911"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/categories?post=601911"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/tags?post=601911"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/devoteam.info\/en-nl\/wp-json\/wp\/v2\/industry?post=601911"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}