{"id":2494,"date":"2015-07-28T12:20:11","date_gmt":"2015-07-28T12:20:11","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=2494"},"modified":"2015-07-28T12:20:11","modified_gmt":"2015-07-28T12:20:11","slug":"using-multiple-aggregates-sum-count-avg-in-a-rethinkdb-query","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/using-multiple-aggregates-sum-count-avg-in-a-rethinkdb-query\/","title":{"rendered":"Using multiple aggregates (SUM, COUNT, AVG) in a RethinkDB query"},"content":{"rendered":"<p>With a RethinkDB query, you can&#8217;t do &#8220;count&#8221; and &#8220;sum&#8221; quite the same as you&#8217;d do in SQL.<\/p>\n<p>Since it uses a map-reduce style engine underneath, you set count to &#8220;1&#8221; on each of your rows and then add these up later:<\/p>\n<pre lang=\"Javascript\">\nr.db('performance')\n .table('query_timings')\n .pluck('DbId')\n .group('DbId')\n .map(function(row) {\n  return {\n    DbId: row('DbId'),\n    Duration: row('Duration'),\n    count: 1\n  }\n  })\n  .reduce(function(left, right) {\n    var dur = left('Duration').add(right('Duration'));\n    var cnt = left('count').add(right('count'));    \n        \n    var avg = cnt > 0 ? dur \/ avg : 0;\n    \n    return {\n      Duration: dur,\n      count: cnt,\n      avg: avg\n    }\n  })\n<\/pre>\n<p>Note however, that with this implementation you&#8217;re computing the average over and over, which is not ideal. <\/p>\n<p>If you want to do &#8220;count distinct&#8221; you&#8217;d want to create a hashmap to track the distinct values:<\/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  .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  .ungroup()\n  .map(function(group) {\n    return {\n        'DbId': group('group'),\n        'found': group('reduction')('found')\n    }\n  })\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>With a RethinkDB query, you can&#8217;t do &#8220;count&#8221; and &#8220;sum&#8221; quite the same as you&#8217;d do in SQL. Since it uses a map-reduce style engine underneath, you set count to &#8220;1&#8221; on each of your rows and then add these up later: r.db(&#8216;performance&#8217;) .table(&#8216;query_timings&#8217;) .pluck(&#8216;DbId&#8217;) .group(&#8216;DbId&#8217;) .map(function(row) { return { DbId: row(&#8216;DbId&#8217;), Duration: row(&#8216;Duration&#8217;), count: &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.garysieling.com\/blog\/using-multiple-aggregates-sum-count-avg-in-a-rethinkdb-query\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using multiple aggregates (SUM, COUNT, AVG) in a RethinkDB query&#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,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4],"tags":[160,462,466],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2494"}],"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=2494"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2494\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=2494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=2494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=2494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}