{"id":2496,"date":"2015-07-27T02:56:25","date_gmt":"2015-07-27T02:56:25","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=2496"},"modified":"2015-07-27T02:56:25","modified_gmt":"2015-07-27T02:56:25","slug":"writing-a-count-distinct-query-in-rethinkdb","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/","title":{"rendered":"Writing a &#8220;count distinct&#8221; query in RethinkDB"},"content":{"rendered":"<p>Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &#8220;count distinct&#8221; style queries.<\/p>\n<p>For this example we want to write a ReQL query that looks like this:<\/p>\n<pre lang=\"SQL\">\nselect count(distinct IP), DbID from logs;\n<\/pre>\n<p>The first step is to group the data by your aggregation field, and add a tracking object. We&#8217;ll use this map for counting later. Note here that it is tempted to declare this as a nested object inside the return &#8211; for me this did not work.<\/p>\n<p>In addition, RethinkDB internally creates it&#8217;s own Javascript objects, which is what allows you to execute a series of functions on them. You can&#8217;t do &#8220;var o = {}&#8221;, or it will fail later.<\/p>\n<pre lang=\"Javascript\">\nr.db('performance')\n .table('query_timings')\n .group('DbId')\n .map(function(row) {\n    var IP = row('IP');\n    \n    var o = r.object(IP, 1);\n   \n    return {\n      DbId: row('DbId'),\n      IP: IP,\n      o\n    }\n  })\n<\/pre>\n<p>To do the counting, we find our previous counting map and merge it (duplicate keys get overridden &#8211; that&#8217;s where the distinct comes in). Once complete, you can also return the list of distinct values if you like. Again, resist the temptation to think that because this is Javascript you can use existing Javascript code to merge objects (e.g. extend\/apply or the &#8220;hasOwnProperty&#8221; method) &#8211; these will not work.<\/p>\n<pre lang=\"Javascript\">\n  .reduce(function(left, right) {\n    var qL = left('o');\n    var qR = right('o');\n  \n    var m = qL.merge(qR);\n      \n    return {\n      DbId: left('DbId'),\n      IPs: m.keys(),\n      found: m.keys().count(),\n      o: m\n    }\n  })\n<\/pre>\n<p>Once you have this done, you&#8217;ll have objects with two keys, &#8220;group&#8221; and &#8220;reduction&#8221;. You can fix this by ungrouping the results like so:<\/p>\n<pre lang=\"Javascript\">\n  .ungroup()\n  .map(function(group) {\n    return {\n        'DbId': group('group'),\n        'found': group('reduction')('found')\n    }\n  })\n<\/pre>\n<p>And after a lot of work, you get your data back:<\/p>\n<pre lang=\"Javascript\">\n[\n  {\n    \"DbId\":  \"db027ceeffa00749a2b9e6a11f0003c13c\" ,\n    \"found\": 2\n  }\n]\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &#8220;count distinct&#8221; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We&#8217;ll &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Writing a &#8220;count distinct&#8221; query in RethinkDB&#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,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=\"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &quot;count distinct&quot; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We&#039;ll\" \/>\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\/writing-a-count-distinct-query-in-rethinkdb\/\" \/>\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=\"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling\" \/>\n\t\t<meta property=\"og:description\" content=\"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &quot;count distinct&quot; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We&#039;ll\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2015-07-27T02:56:25+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2015-07-27T02:56:25+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &quot;count distinct&quot; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We&#039;ll\" \/>\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\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#blogposting\",\"name\":\"Writing a \\u201ccount distinct\\u201d query in RethinkDB - Gary Sieling\",\"headline\":\"Writing a &#8220;count distinct&#8221; query in RethinkDB\",\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\"},\"datePublished\":\"2015-07-27T02:56:25+00:00\",\"dateModified\":\"2015-07-27T02:56:25+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#webpage\"},\"articleSection\":\"Code Examples, databases, reql, rethinkdb, sql\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#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\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#listItem\",\"name\":\"Writing a &#8220;count distinct&#8221; query in RethinkDB\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#listItem\",\"position\":3,\"name\":\"Writing a &#8220;count distinct&#8221; query in RethinkDB\",\"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\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#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\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#webpage\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/\",\"name\":\"Writing a \\u201ccount distinct\\u201d query in RethinkDB - Gary Sieling\",\"description\":\"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for \\\"count distinct\\\" style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We'll\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/writing-a-count-distinct-query-in-rethinkdb\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"datePublished\":\"2015-07-27T02:56:25+00:00\",\"dateModified\":\"2015-07-27T02:56:25+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":"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling","description":"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for \"count distinct\" style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We'll","canonical_url":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#blogposting","name":"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling","headline":"Writing a &#8220;count distinct&#8221; query in RethinkDB","author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"publisher":{"@id":"https:\/\/www.garysieling.com\/blog\/#organization"},"datePublished":"2015-07-27T02:56:25+00:00","dateModified":"2015-07-27T02:56:25+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#webpage"},"isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#webpage"},"articleSection":"Code Examples, databases, reql, rethinkdb, sql"},{"@type":"BreadcrumbList","@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#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\/writing-a-count-distinct-query-in-rethinkdb\/#listItem","name":"Writing a &#8220;count distinct&#8221; query in RethinkDB"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#listItem","position":3,"name":"Writing a &#8220;count distinct&#8221; query in RethinkDB","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\/writing-a-count-distinct-query-in-rethinkdb\/#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\/writing-a-count-distinct-query-in-rethinkdb\/#webpage","url":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/","name":"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling","description":"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for \"count distinct\" style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We'll","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/#breadcrumblist"},"author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"creator":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"datePublished":"2015-07-27T02:56:25+00:00","dateModified":"2015-07-27T02:56:25+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":"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling","og:description":"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &quot;count distinct&quot; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We'll","og:url":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/","article:published_time":"2015-07-27T02:56:25+00:00","article:modified_time":"2015-07-27T02:56:25+00:00","twitter:card":"summary_large_image","twitter:title":"Writing a \u201ccount distinct\u201d query in RethinkDB - Gary Sieling","twitter:description":"Writing queries to compute aggregates in RethinkDB is fairly simple; not so for &quot;count distinct&quot; style queries. For this example we want to write a ReQL query that looks like this: select count(distinct IP), DbID from logs; The first step is to group the data by your aggregation field, and add a tracking object. We'll"},"aioseo_meta_data":{"post_id":"2496","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:28:29","updated":"2026-07-06 01:14:47","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\tWriting a \u201ccount distinct\u201d query in RethinkDB\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":"Writing a &#8220;count distinct&#8221; query in RethinkDB","link":"https:\/\/www.garysieling.com\/blog\/writing-a-count-distinct-query-in-rethinkdb\/"}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2496"}],"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=2496"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2496\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=2496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=2496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=2496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}