You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The previous MapReduce view creates an index that is keyed on the username and whose counts all active email. As the reducer is `_count`, the view outputs the total email count for the selection of data queried. It is suitable for counting the registered users.
245
+
The previous MapReduce view creates an index that is keyed on the `team` the user belongs to, but only includes those with a verified email address. As the reducer is `_count`, the view outputs the number of rows in the view e.g the number of verified users in the database.
246
+
247
+
```json
248
+
{"rows":[
249
+
{"key":null,"value":10010}
250
+
]}
251
+
```
252
+
{: codeblock}
253
+
254
+
By adding `?group=true`, the counts are grouped by distinct keys so the database outputs counts by team membership:
255
+
256
+
```json
257
+
{"rows":[
258
+
{"key":"blue","value":1409},
259
+
{"key":"green","value":1439},
260
+
{"key":"indigo","value":1425},
261
+
{"key":"orange","value":1432},
262
+
{"key":"red","value":1414},
263
+
{"key":"violet","value":1443},
264
+
{"key":"yellow","value":1448}
265
+
]}
266
+
```
267
+
{: codeblock}
268
+
269
+
Switching the reducer off allows the same view to be used for selection of a single team's members `?key="orange"&reduce=false&limit=5`:
The numeric reducers `_stats`/`_sum`act upon the value (the emit function's second parameter) which can be a number, array, or object. Consider the following MapReduce definition on the `products` partitioned database:
285
+
The `_sum`reducer totalizes a MapReduce view's emitted numeric values. The view's value can be a number, an array of numbers, or an object containing numeric values. Consider the following MapReduce definition on a database of products:
The view is keyed on the type of the product, and the value is an object that contains two values: price and tax. The `_sum`reduce calculates totals for each attribute of the object that it finds:
299
+
The view is keyed on the type of the product, and the value is an object that contains two values: `price` and `tax`. The `_sum`reducer calculates totals for both the `price` and `tax` values across the view:
257
300
258
301
```json
259
302
{"rows":[
@@ -262,22 +305,25 @@ The view is keyed on the type of the product, and the value is an object that co
262
305
```
263
306
{: codeblock}
264
307
265
-
Or add`?group=true` when querying the view. The output is grouped and summed by a unique key, in this case, `type`:
308
+
By adding`?group=true` when querying the view, the output is grouped and summed by a unique key, in this case, the product type:
The numeric reducers also calculate multiple reductions when the value of an index is an array of numbers:
318
+
#### Stats reducer
319
+
{: #built-in-reduce-functions-stats-reducer}
320
+
321
+
Like the `_sum` reducer, the `_stats` reducer works on numbers, objects with numeric values or arrays of numbers, returning counts, sums, minimum & maximum values and a sum of the square of the values, which is useful for variance or standard deviation calculations:
Unlike the numeric reducers `_sum` and `_stats` which act upon the index's value, the `_approx_count_distinct` reducer uses the view's _key_. It estimates the number of distinct keys found in the MapReduce view using an algorithm which uses far less memory than an exact count distinct algorithm would consume:
355
+
356
+
```json
357
+
{
358
+
"views": {
359
+
"estimateIpCount": {
360
+
"map": "function (doc) {\n emit(doc.ip, 1);\n}",
361
+
"reduce": "_approx_count_distinct"
362
+
}
363
+
}
364
+
}
365
+
```
366
+
{: codeblock}
367
+
368
+
The previous view definition aims to estimate the number of distinct IP addresses in a database of server logs. The document's `ip` is emitted as the index's _key_ so that the `_approx_count_distinct` reducer can estimate the count of distinct keys:
306
369
307
370
```json
308
371
{"rows":[
309
-
{"key":"product","value":3}
372
+
{"key":null,"value":100528}
310
373
]}
311
374
```
312
375
{: codeblock}
313
376
314
-
The `_approx_count_distinct_reducer` acts upon the _key_ of the index, as opposed to the numeric reducers that act upon the index's _value_.
377
+
#### The top/bottom reducers
378
+
{: #built-in-reduce-functions-top-bottom-reducer}
379
+
380
+
The `_top_x` and `_bottom_x` reducers (where `x` is a number between 1 and 100) return an array of the top x or bottom x _values_ in a view grouping, respectively. For example, in a gaming application, a view can be created keyed on the user id and whose value is the score that the user achieved. This view can be used to create a scoreboard of the best or worst scores:
If we query the view without any parameters, the top three scores in the entire view are returned:
315
395
316
396
```json
317
397
{"rows":[
318
-
{"key":null,"value":2}
398
+
{"key":null,"value":[99,98,97]}
319
399
]}
320
400
```
321
401
{: codeblock}
322
402
403
+
With grouping (`?group=true`), each distinct user's top three scores are returned:
404
+
405
+
```json
406
+
{"rows":[
407
+
{"key":"user082","value":[99,98,97]},
408
+
{"key":"user291","value":[85,72,42]},
409
+
{"key":"user452","value":[55,51,30]}
410
+
]}
411
+
```
412
+
{: codeblock}
413
+
414
+
#### The first/last reducers
415
+
{: #built-in-reduce-functions-first-last-reducer}
416
+
417
+
The `_first`/`_last` reducers return the _value_ of the first or last _key_ in a view grouping, respectively. If we have an IoT application storing readings from many devices periodically, we can create a view keyed on the device id & the time the reading was taken. The view's _value_ is the entire document:
This view produces keys and values of this form, with the view sorted by `deviceid` and `timestamp`. The rows considered the "first" and "last" readings for each device are highlighted:
432
+
433
+
| key | value | First reading (group_level=1) | Last reading (group_level=1) |
|`_count`| Produces the row count for a specific key. The values can be any valid JSON. |
326
469
|`_stats`| Produces a JSON structure that contains the sum, the count, the min, the max, and the sum-squared values. All values must be numeric. |
327
470
|`_sum`| Produces the sum of all values for a key. The values must be numeric. |
328
471
|`_approx_count_distinct`| Approximates the number of distinct keys in a view index by using a variant of the [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog){: external} algorithm. |
472
+
|`_top_x`/`_bottom_x`| Returns an array of the top x or bottom x _values_ in the view grouping as an array, where `x` is a number between 1 and 100. |
473
+
|`_first`/`_last`| Returns the _values_ of the lowest or highest sorting _key_, respectively, for each view group. |
Most customers find that built-in reducers are sufficient to perform aggregations on the view `key-value` pairs emitted from their Map functions. However, for unusual use-cases, a JavaScript reduce function can be supplied instead of the name of one of the built-in reducers.
335
480
481
+
Custom reduce functions are much slower and more difficult to maintain than built-in reducers, so check if a use-case can be satisfied with a built-in reducer before writing a custom one.
482
+
{: tip}
483
+
336
484
Reduce functions are passed three arguments in the following order:
0 commit comments