UNPKG

2.17 kBJavaScriptView Raw
1var es = require('event-stream');
2var semver = require('semver');
3var debug = require('debug')('mongodb-collection-sample');
4var ReservoirSampler = require('./reservoir-sampler');
5var 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 */
22function 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 */
47module.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
62module.exports.getSampler = getSampler;