{"id":3437,"date":"2016-03-16T12:35:59","date_gmt":"2016-03-16T12:35:59","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=3437"},"modified":"2016-03-16T12:35:59","modified_gmt":"2016-03-16T12:35:59","slug":"rethinkdb-inner-join-example","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/","title":{"rendered":"RethinkDB: INNER JOIN Example"},"content":{"rendered":"<p>One way to to do an inner join in RethinkDB with the eqJoin function:<\/p>\n<pre lang=\"javascript\">r.db('test')\n .table('user_actions')\n .filter({file_name: 'test2.pdf'})\n .eqJoin('user_id', r.table('users'))\n<\/pre>\n<p>The biggest disadvantage to this API is that you can&#8217;t easily reverse the order of the tables. In this case, I&#8217;m taking users and adding audit information to them, and in SQL I would be inclined to reverse the order of the join. While this is functionally identical, you may find cases where this forces you to think differently about the process.<\/p>\n<pre lang=\"javascript\">{\n  \"left\": {\n    \"action\":  \"open file\" ,\n    \"file_name\":  \"test2.pdf\" ,\n    \"id\":  \"07123881-5d95-4596-b0b4-3b1f50860bfe\" ,\n    \"user_id\":  \"450e77d6-d5c6-4533-b2d7-c0158bb097c9\"\n  } ,\n  \"right\": {\n    \"first_name\":  \"test\" ,\n    \"id\":  \"450e77d6-d5c6-4533-b2d7-c0158bb097c9\" ,\n    \"work_history\": [\n      {\n        \"role\":  \"role 1\"\n      },\n      {\n        \"role\":  \"role 2\"\n      }\n    ]\n  }\n}<\/pre>\n<p>Note that the above result makes objects called &#8220;left&#8221; and &#8220;right&#8221; in the result, which is not typically what you&#8217;d want &#8211; you can fix this by adding .zip:<\/p>\n<pre lang=\"javascript\">\nr.db('test')\n .table('user_actions')\n .filter({file_name: 'test2.pdf'})\n .eqJoin('user_id', r.table('users'))\n .zip()\n<\/pre>\n<p>The other way to do this is with &#8220;innerJoin&#8221; which requires more effort, but is more flexible and lets you write things that are exact equivalences to SQL:<\/p>\n<pre lang=\"javascript\">\nr.db('test')\n .table('user_actions')\n .filter({file_name: 'test2.pdf'})\n .innerJoin(r.table('users'),\n    (action, user) => \n      action('user_id').eq(user('id')))\n<\/pre>\n<p>And this is the final output:<\/p>\n<pre lang=\"javascript\">\n{\n  \"action\":  \"open file\" ,\n  \"file_name\":  \"test2.pdf\" ,\n  \"first_name\":  \"test\" ,\n  \"id\":  \"450e77d6-d5c6-4533-b2d7-c0158bb097c9\" ,\n  \"user_id\":  \"450e77d6-d5c6-4533-b2d7-c0158bb097c9\" ,\n  \"work_history\": [\n    {\n      \"role\":  \"role 1\"\n    } ,\n    {\n      \"role\":  \"role 2\"\n    }\n  ]\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>One way to to do an inner join in RethinkDB with the eqJoin function: r.db(&#8216;test&#8217;) .table(&#8216;user_actions&#8217;) .filter({file_name: &#8216;test2.pdf&#8217;}) .eqJoin(&#8216;user_id&#8217;, r.table(&#8216;users&#8217;)) The biggest disadvantage to this API is that you can&#8217;t easily reverse the order of the tables. In this case, I&#8217;m taking users and adding audit information to them, and in SQL I would be &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;RethinkDB: INNER JOIN Example&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[4],"tags":[160,302,462,466,523],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.9 - aioseo.com -->\n\t<meta name=\"description\" content=\"One way to to do an inner join in RethinkDB with the eqJoin function: r.db(&#039;test&#039;) .table(&#039;user_actions&#039;) .filter({file_name: &#039;test2.pdf&#039;}) .eqJoin(&#039;user_id&#039;, r.table(&#039;users&#039;)) The biggest disadvantage to this API is that you can&#039;t easily reverse the order of the tables. In this case, I&#039;m taking users and adding audit information to them, and in SQL I would be\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"gary\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.9\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Gary Sieling - Software Engineer\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"RethinkDB: INNER JOIN Example - Gary Sieling\" \/>\n\t\t<meta property=\"og:description\" content=\"One way to to do an inner join in RethinkDB with the eqJoin function: r.db(&#039;test&#039;) .table(&#039;user_actions&#039;) .filter({file_name: &#039;test2.pdf&#039;}) .eqJoin(&#039;user_id&#039;, r.table(&#039;users&#039;)) The biggest disadvantage to this API is that you can&#039;t easily reverse the order of the tables. In this case, I&#039;m taking users and adding audit information to them, and in SQL I would be\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2016-03-16T12:35:59+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2016-03-16T12:35:59+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"RethinkDB: INNER JOIN Example - Gary Sieling\" \/>\n\t\t<meta name=\"twitter:description\" content=\"One way to to do an inner join in RethinkDB with the eqJoin function: r.db(&#039;test&#039;) .table(&#039;user_actions&#039;) .filter({file_name: &#039;test2.pdf&#039;}) .eqJoin(&#039;user_id&#039;, r.table(&#039;users&#039;)) The biggest disadvantage to this API is that you can&#039;t easily reverse the order of the tables. In this case, I&#039;m taking users and adding audit information to them, and in SQL I would be\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#blogposting\",\"name\":\"RethinkDB: INNER JOIN Example - Gary Sieling\",\"headline\":\"RethinkDB: INNER JOIN Example\",\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\"},\"datePublished\":\"2016-03-16T12:35:59+00:00\",\"dateModified\":\"2016-03-16T12:35:59+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#webpage\"},\"articleSection\":\"Code Examples, databases, javascript, reql, rethinkdb, sql\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.garysieling.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"name\":\"Code Examples\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"position\":2,\"name\":\"Code Examples\",\"item\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#listItem\",\"name\":\"RethinkDB: INNER JOIN Example\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#listItem\",\"position\":3,\"name\":\"RethinkDB: INNER JOIN Example\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"name\":\"Code Examples\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\",\"name\":\"Gary Sieling\",\"description\":\"Software Engineer\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/\",\"name\":\"gary\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0be925276d848ffe98a6a9dc8cf33e67?s=96&d=identicon&r=g\",\"width\":96,\"height\":96,\"caption\":\"gary\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#webpage\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/\",\"name\":\"RethinkDB: INNER JOIN Example - Gary Sieling\",\"description\":\"One way to to do an inner join in RethinkDB with the eqJoin function: r.db('test') .table('user_actions') .filter({file_name: 'test2.pdf'}) .eqJoin('user_id', r.table('users')) The biggest disadvantage to this API is that you can't easily reverse the order of the tables. In this case, I'm taking users and adding audit information to them, and in SQL I would be\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-inner-join-example\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"datePublished\":\"2016-03-16T12:35:59+00:00\",\"dateModified\":\"2016-03-16T12:35:59+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/\",\"name\":\"Gary Sieling\",\"description\":\"Software Engineer\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"RethinkDB: INNER JOIN Example - Gary Sieling","description":"One way to to do an inner join in RethinkDB with the eqJoin function: r.db('test') .table('user_actions') .filter({file_name: 'test2.pdf'}) .eqJoin('user_id', r.table('users')) The biggest disadvantage to this API is that you can't easily reverse the order of the tables. In this case, I'm taking users and adding audit information to them, and in SQL I would be","canonical_url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#blogposting","name":"RethinkDB: INNER JOIN Example - Gary Sieling","headline":"RethinkDB: INNER JOIN Example","author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"publisher":{"@id":"https:\/\/www.garysieling.com\/blog\/#organization"},"datePublished":"2016-03-16T12:35:59+00:00","dateModified":"2016-03-16T12:35:59+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#webpage"},"isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#webpage"},"articleSection":"Code Examples, databases, javascript, reql, rethinkdb, sql"},{"@type":"BreadcrumbList","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.garysieling.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","name":"Code Examples"}},{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","position":2,"name":"Code Examples","item":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#listItem","name":"RethinkDB: INNER JOIN Example"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#listItem","position":3,"name":"RethinkDB: INNER JOIN Example","previousItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","name":"Code Examples"}}]},{"@type":"Organization","@id":"https:\/\/www.garysieling.com\/blog\/#organization","name":"Gary Sieling","description":"Software Engineer","url":"https:\/\/www.garysieling.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author","url":"https:\/\/www.garysieling.com\/blog\/author\/gary\/","name":"gary","image":{"@type":"ImageObject","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/0be925276d848ffe98a6a9dc8cf33e67?s=96&d=identicon&r=g","width":96,"height":96,"caption":"gary"}},{"@type":"WebPage","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#webpage","url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/","name":"RethinkDB: INNER JOIN Example - Gary Sieling","description":"One way to to do an inner join in RethinkDB with the eqJoin function: r.db('test') .table('user_actions') .filter({file_name: 'test2.pdf'}) .eqJoin('user_id', r.table('users')) The biggest disadvantage to this API is that you can't easily reverse the order of the tables. In this case, I'm taking users and adding audit information to them, and in SQL I would be","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/#breadcrumblist"},"author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"creator":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"datePublished":"2016-03-16T12:35:59+00:00","dateModified":"2016-03-16T12:35:59+00:00"},{"@type":"WebSite","@id":"https:\/\/www.garysieling.com\/blog\/#website","url":"https:\/\/www.garysieling.com\/blog\/","name":"Gary Sieling","description":"Software Engineer","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.garysieling.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Gary Sieling - Software Engineer","og:type":"article","og:title":"RethinkDB: INNER JOIN Example - Gary Sieling","og:description":"One way to to do an inner join in RethinkDB with the eqJoin function: r.db('test') .table('user_actions') .filter({file_name: 'test2.pdf'}) .eqJoin('user_id', r.table('users')) The biggest disadvantage to this API is that you can't easily reverse the order of the tables. In this case, I'm taking users and adding audit information to them, and in SQL I would be","og:url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/","article:published_time":"2016-03-16T12:35:59+00:00","article:modified_time":"2016-03-16T12:35:59+00:00","twitter:card":"summary_large_image","twitter:title":"RethinkDB: INNER JOIN Example - Gary Sieling","twitter:description":"One way to to do an inner join in RethinkDB with the eqJoin function: r.db('test') .table('user_actions') .filter({file_name: 'test2.pdf'}) .eqJoin('user_id', r.table('users')) The biggest disadvantage to this API is that you can't easily reverse the order of the tables. In this case, I'm taking users and adding audit information to them, and in SQL I would be"},"aioseo_meta_data":{"post_id":"3437","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"created":"2023-02-04 16:44:01","updated":"2026-07-06 01:38:53","ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.garysieling.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/\" title=\"Code Examples\">Code Examples<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tRethinkDB: INNER JOIN Example\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.garysieling.com\/blog"},{"label":"Code Examples","link":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/"},{"label":"RethinkDB: INNER JOIN Example","link":"https:\/\/www.garysieling.com\/blog\/rethinkdb-inner-join-example\/"}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/3437"}],"collection":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/comments?post=3437"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/3437\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=3437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=3437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=3437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}