1 | var es = require('event-stream');
|
2 | var semver = require('semver');
|
3 | var debug = require('debug')('mongodb-collection-sample');
|
4 | var ReservoirSampler = require('./reservoir-sampler');
|
5 | var NativeSampler = require('./native-sampler');
|
6 |
|
7 | /**
|
8 | * Test the MongoDB kernel version `db` is using and return
|
9 | * a `stream.Readable` that will use the native `$sample` aggregation
|
10 | * operator if available or fall back to a client-side reservoir sample.
|
11 | *
|
12 | * @param {mongodb.DB} db
|
13 | * @param {String} collectionName to source from.
|
14 | * @param {Object} opts
|
15 | * @param {Function} done callback
|
16 | *
|
17 | * @option {Object} query to refine possible samples [default: `{}`].
|
18 | * @option {Number} size of the sample to capture [default: `5`].
|
19 | * @option {Boolean} raw BSON buffers to return [default: `false`].
|
20 | * @option {Object} cursor specification when providing a raw option [default: `{}`].
|
21 | */
|
22 | function getSampler(db, collectionName, opts, done) {
|
23 | db.admin().serverInfo(function(err, res) {
|
24 | if (err) return done(err);
|
25 | var supported = semver.gte(res.version, '3.1.6');
|
26 |
|
27 | debug('has native $sample?', supported);
|
28 | if (!supported) {
|
29 | return done(null, new ReservoirSampler(db, collectionName, opts));
|
30 | }
|
31 | return done(null, new NativeSampler(db, collectionName, opts));
|
32 | });
|
33 | }
|
34 |
|
35 | /**
|
36 | * Take an `_id` and emit the source document.
|
37 | *
|
38 | * @param {mongodb.Db} db
|
39 | * @param {String} collectionName to source from.
|
40 | * @param {Object} [opts]
|
41 | * @option {Object} query to refine possible samples [default: `{}`].
|
42 | * @option {Number} size of the sample to capture [default: `5`].
|
43 | * @option {Boolean} raw BSON buffers to return [default: `false`].
|
44 | * @return {stream.Readable}
|
45 | * @api public
|
46 | */
|
47 | module.exports = function(db, collectionName, opts) {
|
48 | var readable = es.readable(function() {
|
49 | getSampler(db, collectionName, opts, function(err, src) {
|
50 | if (err) {
|
51 | return readable.emit('error', err);
|
52 | }
|
53 |
|
54 | src.on('data', readable.emit.bind(readable, 'data'));
|
55 | src.on('error', readable.emit.bind(readable, 'error'));
|
56 | src.on('end', readable.emit.bind(readable, 'end'));
|
57 | });
|
58 | });
|
59 | return readable;
|
60 | };
|
61 |
|
62 | module.exports.getSampler = getSampler;
|