louischatriot/nedb — pull request #153 by adityamukho (2014-03-07 13:16:12+00:00)
Title: Added .group() function

Ref: http://docs.mongodb.org/manual/reference/method/db.collection.group/

Added a function to the `Cursor` protoype that allows users to **reduce** the result set (after `find()`), allowing operations like aggregation (sum, avg, count, etc) or any other reductor. This function can work in conjunction with `limit()`, `skip()` and `sort()`. The order of the execution pipeline is: `find -> group -> sort -> slice (skip+limit)`.

The function is invoked on the `Cursor` object returned by `find()`, with an object that looks like:
```
key: {
'field1': 1,
'nested.field.2': 1
},
reduce: function (curr, result) {
result.count++;
result.size += curr.size;
},
initial: {
count: 0,
size: 0
},
finalize: function (result) {
result.avg = Math.round(result.size / result.count);
}
```

Unlike the `group()` function in MongoDB, this does not need a `cond` part, since the `find()` operation takes care of that beforehand.

The function returns the `Cursor` on which it was invoked, allowing for chaining sort, skip/limit ops later.

The reduction outputs a resultset that looks like:
```
[
{
field1: 'A',
nested_field_2: 'b',
count: 2,
size: 4,
avg: 2
},
{
field1: 'A',
nested_field_2: 'b1',
count: 3,
size: 9,
avg: 3
},
{
field1: 'B',
nested_field_2: 'b',
count: 1,
size: 4,
avg: 4
},
{
field1: 'B',
nested_field_2: 'b2',
count: 5,
size: 1,
avg: 0
},
...
...
]
```

The field names in the *groupBy* keys have their `.` replaced by `_` so that the subsequent sort function, if present, works properly.

I have tried my best to ensure the function is optimized, and robust. The test suite passes all tests. Have tested this function on a DB with ~380,000 records and the same reductor as shown above, and it works fine. Haven't added test cases directly to the project yet, though. Will do it if this looks likely to be merged :).

PS. The browser versions were auto-generated using the build script. I haven't modified them manually. The test page shows no errors there either.