프로젝트

일반

사용자정보

통계
| 개정판:

root / HServer / 00.Server / 00.Program / node_modules / mquery / README.md

이력 | 보기 | 이력해설 | 다운로드 (31 KB)

1 39 HKM
# mquery
2
3
`mquery` is a fluent mongodb query builder designed to run in multiple environments.
4
5
## Features
6
7
  - fluent query builder api
8
  - custom base query support
9
  - MongoDB 2.4 geoJSON support
10
  - method + option combinations validation
11
  - node.js driver compatibility
12
  - environment detection
13
  - [debug](https://github.com/visionmedia/debug) support
14
  - separated collection implementations for maximum flexibility
15
16
[![Build Status](https://travis-ci.org/aheckmann/mquery.png)](https://travis-ci.org/aheckmann/mquery)
17
18
## Use
19
20
```js
21
require('mongodb').connect(uri, function (err, db) {
22
  if (err) return handleError(err);
23
24
  // get a collection
25
  var collection = db.collection('artists');
26
27
  // pass it to the constructor
28
  mquery(collection).find({..}, callback);
29
30
  // or pass it to the collection method
31
  mquery().find({..}).collection(collection).exec(callback)
32
33
  // or better yet, create a custom query constructor that has it always set
34
  var Artist = mquery(collection).toConstructor();
35
  Artist().find(..).where(..).exec(callback)
36
})
37
```
38
39
`mquery` requires a collection object to work with. In the example above we just pass the collection object created using the official [MongoDB driver](https://github.com/mongodb/node-mongodb-native).
40
41
42
## Fluent API
43
44
- [find](#find)
45
- [findOne](#findOne)
46
- [count](#count)
47
- [remove](#remove)
48
- [update](#update)
49
- [findOneAndUpdate](#findoneandupdate)
50
- [findOneAndRemove](#findoneandremove)
51
- [distinct](#distinct)
52
- [exec](#exec)
53
- [stream](#stream)
54
- [all](#all)
55
- [and](#and)
56
- [box](#box)
57
- [circle](#circle)
58
- [elemMatch](#elemmatch)
59
- [equals](#equals)
60
- [exists](#exists)
61
- [geometry](#geometry)
62
- [gt](#gt)
63
- [gte](#gte)
64
- [in](#in)
65
- [intersects](#intersects)
66
- [lt](#lt)
67
- [lte](#lte)
68
- [maxDistance](#maxdistance)
69
- [mod](#mod)
70
- [ne](#ne)
71
- [nin](#nin)
72
- [nor](#nor)
73
- [near](#near)
74
- [or](#or)
75
- [polygon](#polygon)
76
- [regex](#regex)
77
- [select](#select)
78
- [selected](#selected)
79
- [selectedInclusively](#selectedinclusively)
80
- [selectedExclusively](#selectedexclusively)
81
- [size](#size)
82
- [slice](#slice)
83
- [within](#within)
84
- [where](#where)
85
- [$where](#where-1)
86
- [batchSize](#batchsize)
87
- [comment](#comment)
88
- [hint](#hint)
89
- [limit](#limit)
90
- [maxScan](#maxscan)
91
- [maxTime](#maxtime)
92
- [skip](#skip)
93
- [sort](#sort)
94
- [read](#read)
95
- [slaveOk](#slaveok)
96
- [snapshot](#snapshot)
97
- [tailable](#tailable)
98
99
## Helpers
100
101
- [collection](#collection)
102
- [then](#then)
103
- [thunk](#thunk)
104
- [merge](#mergeobject)
105
- [setOptions](#setoptionsoptions)
106
- [setTraceFunction](#settracefunctionfunc)
107
- [mquery.setGlobalTraceFunction](#mquerysetglobaltracefunctionfunc)
108
- [mquery.canMerge](#mquerycanmerge)
109
- [mquery.use$geoWithin](#mqueryusegeowithin)
110
111
### find()
112
113
Declares this query a _find_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed.
114
115
```js
116
mquery().find()
117
mquery().find(match)
118
mquery().find(callback)
119
mquery().find(match, function (err, docs) {
120
  assert(Array.isArray(docs));
121
})
122
```
123
124
### findOne()
125
126
Declares this query a _findOne_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed.
127
128
```js
129
mquery().findOne()
130
mquery().findOne(match)
131
mquery().findOne(callback)
132
mquery().findOne(match, function (err, doc) {
133
  if (doc) {
134
    // the document may not be found
135
    console.log(doc);
136
  }
137
})
138
```
139
140
### count()
141
142
Declares this query a _count_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed.
143
144
```js
145
mquery().count()
146
mquery().count(match)
147
mquery().count(callback)
148
mquery().count(match, function (err, number){
149
  console.log('we found %d matching documents', number);
150
})
151
```
152
153
### remove()
154
155
Declares this query a _remove_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed.
156
157
```js
158
mquery().remove()
159
mquery().remove(match)
160
mquery().remove(callback)
161
mquery().remove(match, function (err){})
162
```
163
164
### update()
165
166
Declares this query an _update_ query. Optionally pass an update document, match clause, options or callback. If a callback is passed, the query is executed. To force execution without passing a callback, run `update(true)`.
167
168
```js
169
mquery().update()
170
mquery().update(match, updateDocument)
171
mquery().update(match, updateDocument, options)
172
173
// the following all execute the command
174
mquery().update(callback)
175
mquery().update({$set: updateDocument, callback)
176
mquery().update(match, updateDocument, callback)
177
mquery().update(match, updateDocument, options, function (err, result){})
178
mquery().update(true) // executes (unsafe write)
179
```
180
181
##### the update document
182
183
All paths passed that are not `$atomic` operations will become `$set` ops. For example:
184
185
```js
186
mquery(collection).where({ _id: id }).update({ title: 'words' }, callback)
187
```
188
189
becomes
190
191
```js
192
collection.update({ _id: id }, { $set: { title: 'words' }}, callback)
193
```
194
195
This behavior can be overridden using the `overwrite` option (see below).
196
197
##### options
198
199
Options are passed to the `setOptions()` method.
200
201
- overwrite
202
203
Passing an empty object `{ }` as the update document will result in a no-op unless the `overwrite` option is passed. Without the `overwrite` option, the update operation will be ignored and the callback executed without sending the command to MongoDB to prevent accidently overwritting documents in the collection.
204
205
```js
206
var q = mquery(collection).where({ _id: id }).setOptions({ overwrite: true });
207
q.update({ }, callback); // overwrite with an empty doc
208
```
209
210
The `overwrite` option isn't just for empty objects, it also provides a means to override the default `$set` conversion and send the update document as is.
211
212
```js
213
// create a base query
214
var base = mquery({ _id: 108 }).collection(collection).toConstructor();
215
216
base().findOne(function (err, doc) {
217
  console.log(doc); // { _id: 108, name: 'cajon' })
218
219
  base().setOptions({ overwrite: true }).update({ changed: true }, function (err) {
220
    base.findOne(function (err, doc) {
221
      console.log(doc); // { _id: 108, changed: true }) - the doc was overwritten
222
    });
223
  });
224
})
225
```
226
227
- multi
228
229
Updates only modify a single document by default. To update multiple documents, set the `multi` option to `true`.
230
231
```js
232
mquery()
233
  .collection(coll)
234
  .update({ name: /^match/ }, { $addToSet: { arr: 4 }}, { multi: true }, callback)
235
236
// another way of doing it
237
mquery({ name: /^match/ })
238
  .collection(coll)
239
  .setOptions({ multi: true })
240
  .update({ $addToSet: { arr: 4 }}, callback)
241
242
// update multiple documents with an empty doc
243
var q = mquery(collection).where({ name: /^match/ });
244
q.setOptions({ multi: true, overwrite: true })
245
q.update({ });
246
q.update(function (err, result) {
247
  console.log(arguments);
248
});
249
```
250
251
### findOneAndUpdate()
252
253
Declares this query a _findAndModify_ with update query. Optionally pass a match clause, update document, options, or callback. If a callback is passed, the query is executed.
254
255
When executed, the first matching document (if found) is modified according to the update document and passed back to the callback.
256
257
##### options
258
259
Options are passed to the `setOptions()` method.
260
261
- `new`: boolean - true to return the modified document rather than the original. defaults to true
262
- `upsert`: boolean - creates the object if it doesn't exist. defaults to false
263
- `sort`: if multiple docs are found by the match condition, sets the sort order to choose which doc to update
264
265
```js
266
query.findOneAndUpdate()
267
query.findOneAndUpdate(updateDocument)
268
query.findOneAndUpdate(match, updateDocument)
269
query.findOneAndUpdate(match, updateDocument, options)
270
271
// the following all execute the command
272
query.findOneAndUpdate(callback)
273
query.findOneAndUpdate(updateDocument, callback)
274
query.findOneAndUpdate(match, updateDocument, callback)
275
query.findOneAndUpdate(match, updateDocument, options, function (err, doc) {
276
  if (doc) {
277
    // the document may not be found
278
    console.log(doc);
279
  }
280
})
281
 ```
282
283
### findOneAndRemove()
284
285
Declares this query a _findAndModify_ with remove query. Optionally pass a match clause, options, or callback. If a callback is passed, the query is executed.
286
287
When executed, the first matching document (if found) is modified according to the update document, removed from the collection and passed to the callback.
288
289
##### options
290
291
Options are passed to the `setOptions()` method.
292
293
- `sort`: if multiple docs are found by the condition, sets the sort order to choose which doc to modify and remove
294
295
```js
296
A.where().findOneAndRemove()
297
A.where().findOneAndRemove(match)
298
A.where().findOneAndRemove(match, options)
299
300
// the following all execute the command
301
A.where().findOneAndRemove(callback)
302
A.where().findOneAndRemove(match, callback)
303
A.where().findOneAndRemove(match, options, function (err, doc) {
304
  if (doc) {
305
    // the document may not be found
306
    console.log(doc);
307
  }
308
})
309
 ```
310
311
### distinct()
312
313
Declares this query a _distinct_ query. Optionally pass the distinct field, a match clause or callback. If a callback is passed the query is executed.
314
315
```js
316
mquery().distinct()
317
mquery().distinct(match)
318
mquery().distinct(match, field)
319
mquery().distinct(field)
320
321
// the following all execute the command
322
mquery().distinct(callback)
323
mquery().distinct(field, callback)
324
mquery().distinct(match, callback)
325
mquery().distinct(match, field, function (err, result) {
326
  console.log(result);
327
})
328
```
329
330
### exec()
331
332
Executes the query.
333
334
```js
335
mquery().findOne().where('route').intersects(polygon).exec(function (err, docs){})
336
```
337
338
### stream()
339
340
Executes the query and returns a stream.
341
342
```js
343
var stream = mquery().find().stream(options);
344
stream.on('data', cb);
345
stream.on('close', fn);
346
```
347
348
Note: this only works with `find()` operations.
349
350
Note: returns the stream object directly from the node-mongodb-native driver. (currently streams1 type stream). Any options will be passed along to the [driver method](http://mongodb.github.io/node-mongodb-native/api-generated/cursor.html#stream).
351
352
-------------
353
354
### all()
355
356
Specifies an `$all` query condition
357
358
```js
359
mquery().where('permission').all(['read', 'write'])
360
```
361
362
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/all/)
363
364
### and()
365
366
Specifies arguments for an `$and` condition
367
368
```js
369
mquery().and([{ color: 'green' }, { status: 'ok' }])
370
```
371
372
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/and/)
373
374
### box()
375
376
Specifies a `$box` condition
377
378
```js
379
var lowerLeft = [40.73083, -73.99756]
380
var upperRight= [40.741404,  -73.988135]
381
382
mquery().where('location').within().box(lowerLeft, upperRight)
383
```
384
385
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/box/)
386
387
### circle()
388
389
Specifies a `$center` or `$centerSphere` condition.
390
391
```js
392
var area = { center: [50, 50], radius: 10, unique: true }
393
query.where('loc').within().circle(area)
394
query.circle('loc', area);
395
396
// for spherical calculations
397
var area = { center: [50, 50], radius: 10, unique: true, spherical: true }
398
query.where('loc').within().circle(area)
399
query.circle('loc', area);
400
```
401
402
- [MongoDB Documentation - center](http://docs.mongodb.org/manual/reference/operator/center/)
403
- [MongoDB Documentation - centerSphere](http://docs.mongodb.org/manual/reference/operator/centerSphere/)
404
405
### elemMatch()
406
407
Specifies an `$elemMatch` condition
408
409
```js
410
query.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}})
411
412
query.elemMatch('comment', function (elem) {
413
  elem.where('author').equals('autobot');
414
  elem.where('votes').gte(5);
415
})
416
```
417
418
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/elemMatch/)
419
420
### equals()
421
422
Specifies the complementary comparison value for the path specified with `where()`.
423
424
```js
425
mquery().where('age').equals(49);
426
427
// is the same as
428
429
mquery().where({ 'age': 49 });
430
```
431
432
### exists()
433
434
Specifies an `$exists` condition
435
436
```js
437
// { name: { $exists: true }}
438
mquery().where('name').exists()
439
mquery().where('name').exists(true)
440
mquery().exists('name')
441
442
// { name: { $exists: false }}
443
mquery().where('name').exists(false);
444
mquery().exists('name', false);
445
```
446
447
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/exists/)
448
449
### geometry()
450
451
Specifies a `$geometry` condition
452
453
```js
454
var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]]
455
query.where('loc').within().geometry({ type: 'Polygon', coordinates: polyA })
456
457
// or
458
var polyB = [[ 0, 0 ], [ 1, 1 ]]
459
query.where('loc').within().geometry({ type: 'LineString', coordinates: polyB })
460
461
// or
462
var polyC = [ 0, 0 ]
463
query.where('loc').within().geometry({ type: 'Point', coordinates: polyC })
464
465
// or
466
query.where('loc').intersects().geometry({ type: 'Point', coordinates: polyC })
467
468
// or
469
query.where('loc').near().geometry({ type: 'Point', coordinates: [3,5] })
470
```
471
472
`geometry()` **must** come after `intersects()`, `within()`, or `near()`.
473
474
The `object` argument must contain `type` and `coordinates` properties.
475
476
- type `String`
477
- coordinates `Array`
478
479
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geometry/)
480
481
### gt()
482
483
Specifies a `$gt` query condition.
484
485
```js
486
mquery().where('clicks').gt(999)
487
```
488
489
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/gt/)
490
491
### gte()
492
493
Specifies a `$gte` query condition.
494
495
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/gte/)
496
497
```js
498
mquery().where('clicks').gte(1000)
499
```
500
501
### in()
502
503
Specifies an `$in` query condition.
504
505
```js
506
mquery().where('author_id').in([3, 48901, 761])
507
```
508
509
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/in/)
510
511
### intersects()
512
513
Declares an `$geoIntersects` query for `geometry()`.
514
515
```js
516
query.where('path').intersects().geometry({
517
    type: 'LineString'
518
  , coordinates: [[180.0, 11.0], [180, 9.0]]
519
})
520
521
// geometry arguments are supported
522
query.where('path').intersects({
523
    type: 'LineString'
524
  , coordinates: [[180.0, 11.0], [180, 9.0]]
525
})
526
```
527
528
**Must** be used after `where()`.
529
530
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geoIntersects/)
531
532
### lt()
533
534
Specifies a `$lt` query condition.
535
536
```js
537
mquery().where('clicks').lt(50)
538
```
539
540
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/lt/)
541
542
### lte()
543
544
Specifies a `$lte` query condition.
545
546
```js
547
mquery().where('clicks').lte(49)
548
```
549
550
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/lte/)
551
552
### maxDistance()
553
554
Specifies a `$maxDistance` query condition.
555
556
```js
557
mquery().where('location').near({ center: [139, 74.3] }).maxDistance(5)
558
```
559
560
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/maxDistance/)
561
562
### mod()
563
564
Specifies a `$mod` condition
565
566
```js
567
mquery().where('count').mod(2, 0)
568
```
569
570
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/mod/)
571
572
### ne()
573
574
Specifies a `$ne` query condition.
575
576
```js
577
mquery().where('status').ne('ok')
578
```
579
580
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/ne/)
581
582
### nin()
583
584
Specifies an `$nin` query condition.
585
586
```js
587
mquery().where('author_id').nin([3, 48901, 761])
588
```
589
590
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/nin/)
591
592
### nor()
593
594
Specifies arguments for an `$nor` condition.
595
596
```js
597
mquery().nor([{ color: 'green' }, { status: 'ok' }])
598
```
599
600
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/nor/)
601
602
### near()
603
604
Specifies arguments for a `$near` or `$nearSphere` condition.
605
606
These operators return documents sorted by distance.
607
608
#### Example
609
610
```js
611
query.where('loc').near({ center: [10, 10] });
612
query.where('loc').near({ center: [10, 10], maxDistance: 5 });
613
query.near('loc', { center: [10, 10], maxDistance: 5 });
614
615
// GeoJSON
616
query.where('loc').near({ center: { type: 'Point', coordinates: [10, 10] }});
617
query.where('loc').near({ center: { type: 'Point', coordinates: [10, 10] }, maxDistance: 5, spherical: true });
618
query.where('loc').near().geometry({ type: 'Point', coordinates: [10, 10] });
619
620
// For a $nearSphere condition, pass the `spherical` option.
621
query.near({ center: [10, 10], maxDistance: 5, spherical: true });
622
```
623
624
[MongoDB Documentation](http://www.mongodb.org/display/DOCS/Geospatial+Indexing)
625
626
### or()
627
628
Specifies arguments for an `$or` condition.
629
630
```js
631
mquery().or([{ color: 'red' }, { status: 'emergency' }])
632
```
633
634
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/or/)
635
636
### polygon()
637
638
Specifies a `$polygon` condition
639
640
```js
641
mquery().where('loc').within().polygon([10,20], [13, 25], [7,15])
642
mquery().polygon('loc', [10,20], [13, 25], [7,15])
643
```
644
645
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/polygon/)
646
647
### regex()
648
649
Specifies a `$regex` query condition.
650
651
```js
652
mquery().where('name').regex(/^sixstepsrecords/)
653
```
654
655
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/regex/)
656
657
### select()
658
659
Specifies which document fields to include or exclude
660
661
```js
662
// 1 means include, 0 means exclude
663
mquery().select({ name: 1, address: 1, _id: 0 })
664
665
// or
666
667
mquery().select('name address -_id')
668
```
669
670
##### String syntax
671
672
When passing a string, prefixing a path with `-` will flag that path as excluded. When a path does not have the `-` prefix, it is included.
673
674
```js
675
// include a and b, exclude c
676
query.select('a b -c');
677
678
// or you may use object notation, useful when
679
// you have keys already prefixed with a "-"
680
query.select({a: 1, b: 1, c: 0});
681
```
682
683
_Cannot be used with `distinct()`._
684
685
### selected()
686
687
Determines if the query has selected any fields.
688
689
```js
690
var query = mquery();
691
query.selected() // false
692
query.select('-name');
693
query.selected() // true
694
```
695
696
### selectedInclusively()
697
698
Determines if the query has selected any fields inclusively.
699
700
```js
701
var query = mquery().select('name');
702
query.selectedInclusively() // true
703
704
var query = mquery();
705
query.selected() // false
706
query.select('-name');
707
query.selectedInclusively() // false
708
query.selectedExclusively() // true
709
```
710
711
### selectedExclusively()
712
713
Determines if the query has selected any fields exclusively.
714
715
```js
716
var query = mquery().select('-name');
717
query.selectedExclusively() // true
718
719
var query = mquery();
720
query.selected() // false
721
query.select('name');
722
query.selectedExclusively() // false
723
query.selectedInclusively() // true
724
```
725
726
### size()
727
728
Specifies a `$size` query condition.
729
730
```js
731
mquery().where('someArray').size(6)
732
```
733
734
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/size/)
735
736
### slice()
737
738
Specifies a `$slice` projection for a `path`
739
740
```js
741
mquery().where('comments').slice(5)
742
mquery().where('comments').slice(-5)
743
mquery().where('comments').slice([-10, 5])
744
```
745
746
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/projection/slice/)
747
748
### within()
749
750
Sets a `$geoWithin` or `$within` argument for geo-spatial queries.
751
752
```js
753
mquery().within().box()
754
mquery().within().circle()
755
mquery().within().geometry()
756
757
mquery().where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true });
758
mquery().where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] });
759
mquery().where('loc').within({ polygon: [[],[],[],[]] });
760
761
mquery().where('loc').within([], [], []) // polygon
762
mquery().where('loc').within([], []) // box
763
mquery().where('loc').within({ type: 'LineString', coordinates: [...] }); // geometry
764
```
765
766
As of mquery 2.0, `$geoWithin` is used by default. This impacts you if running MongoDB < 2.4. To alter this behavior, see [mquery.use$geoWithin](#mqueryusegeowithin).
767
768
**Must** be used after `where()`.
769
770
[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geoWithin/)
771
772
### where()
773
774
Specifies a `path` for use with chaining
775
776
```js
777
// instead of writing:
778
mquery().find({age: {$gte: 21, $lte: 65}});
779
780
// we can instead write:
781
mquery().where('age').gte(21).lte(65);
782
783
// passing query conditions is permitted too
784
mquery().find().where({ name: 'vonderful' })
785
786
// chaining
787
mquery()
788
.where('age').gte(21).lte(65)
789
.where({ 'name': /^vonderful/i })
790
.where('friends').slice(10)
791
.exec(callback)
792
```
793
794
### $where()
795
796
Specifies a `$where` condition.
797
798
Use `$where` when you need to select documents using a JavaScript expression.
799
800
```js
801
query.$where('this.comments.length > 10 || this.name.length > 5').exec(callback)
802
803
query.$where(function () {
804
  return this.comments.length > 10 || this.name.length > 5;
805
})
806
```
807
808
Only use `$where` when you have a condition that cannot be met using other MongoDB operators like `$lt`. Be sure to read about all of [its caveats](http://docs.mongodb.org/manual/reference/operator/where/) before using.
809
810
-----------
811
812
### batchSize()
813
814
Specifies the batchSize option.
815
816
```js
817
query.batchSize(100)
818
```
819
820
_Cannot be used with `distinct()`._
821
822
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.batchSize/)
823
824
### comment()
825
826
Specifies the comment option.
827
828
```js
829
query.comment('login query');
830
```
831
832
_Cannot be used with `distinct()`._
833
834
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/)
835
836
### hint()
837
838
Sets query hints.
839
840
```js
841
mquery().hint({ indexA: 1, indexB: -1 })
842
```
843
844
_Cannot be used with `distinct()`._
845
846
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/hint/)
847
848
### limit()
849
850
Specifies the limit option.
851
852
```js
853
query.limit(20)
854
```
855
856
_Cannot be used with `distinct()`._
857
858
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.limit/)
859
860
### maxScan()
861
862
Specifies the maxScan option.
863
864
```js
865
query.maxScan(100)
866
```
867
868
_Cannot be used with `distinct()`._
869
870
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/maxScan/)
871
872
### maxTime()
873
874
Specifies the maxTimeMS option.
875
876
```js
877
query.maxTime(100)
878
```
879
880
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.maxTimeMS/)
881
882
883
### skip()
884
885
Specifies the skip option.
886
887
```js
888
query.skip(100).limit(20)
889
```
890
891
_Cannot be used with `distinct()`._
892
893
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.skip/)
894
895
### sort()
896
897
Sets the query sort order.
898
899
If an object is passed, key values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`.
900
901
If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with `-` which will be treated as descending.
902
903
```js
904
// these are equivalent
905
query.sort({ field: 'asc', test: -1 });
906
query.sort('field -test');
907
```
908
909
_Cannot be used with `distinct()`._
910
911
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.sort/)
912
913
### read()
914
915
Sets the readPreference option for the query.
916
917
```js
918
mquery().read('primary')
919
mquery().read('p')  // same as primary
920
921
mquery().read('primaryPreferred')
922
mquery().read('pp') // same as primaryPreferred
923
924
mquery().read('secondary')
925
mquery().read('s')  // same as secondary
926
927
mquery().read('secondaryPreferred')
928
mquery().read('sp') // same as secondaryPreferred
929
930
mquery().read('nearest')
931
mquery().read('n')  // same as nearest
932
```
933
934
##### Preferences:
935
936
- `primary` - (default) Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags.
937
- `secondary` - Read from secondary if available, otherwise error.
938
- `primaryPreferred` - Read from primary if available, otherwise a secondary.
939
- `secondaryPreferred` - Read from a secondary if available, otherwise read from the primary.
940
- `nearest` - All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection.
941
942
Aliases
943
944
- `p`   primary
945
- `pp`  primaryPreferred
946
- `s`   secondary
947
- `sp`  secondaryPreferred
948
- `n`   nearest
949
950
##### Preference Tags:
951
952
To keep the separation of concerns between `mquery` and your driver
953
clean, `mquery#read()` no longer handles specifying a second `tags` argument as of version 0.5.
954
If you need to specify tags, pass any non-string argument as the first argument.
955
`mquery` will pass this argument untouched to your collections methods later.
956
For example:
957
958
```js
959
// example of specifying tags using the Node.js driver
960
var ReadPref = require('mongodb').ReadPreference;
961
var preference = new ReadPref('secondary', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }]);
962
mquery(..).read(preference).exec();
963
```
964
965
Read more about how to use read preferences [here](http://docs.mongodb.org/manual/applications/replication/#read-preference) and [here](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences).
966
967
### slaveOk()
968
969
Sets the slaveOk option. `true` allows reading from secondaries.
970
971
**deprecated** use [read()](#read) preferences instead if on mongodb >= 2.2
972
973
```js
974
query.slaveOk() // true
975
query.slaveOk(true)
976
query.slaveOk(false)
977
```
978
979
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/rs.slaveOk/)
980
981
### snapshot()
982
983
Specifies this query as a snapshot query.
984
985
```js
986
mquery().snapshot() // true
987
mquery().snapshot(true)
988
mquery().snapshot(false)
989
```
990
991
_Cannot be used with `distinct()`._
992
993
[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/snapshot/)
994
995
### tailable()
996
997
Sets tailable option.
998
999
```js
1000
mquery().tailable() <== true
1001
mquery().tailable(true)
1002
mquery().tailable(false)
1003
```
1004
1005
_Cannot be used with `distinct()`._
1006
1007
[MongoDB Documentation](http://docs.mongodb.org/manual/tutorial/create-tailable-cursor/)
1008
1009
## Helpers
1010
1011
### collection()
1012
1013
Sets the querys collection.
1014
1015
```js
1016
mquery().collection(aCollection)
1017
```
1018
1019
### then()
1020
1021
Executes the query and returns a promise which will be resolved with the query results or rejected if the query responds with an error.
1022
1023
```js
1024
mquery().find(..).then(success, error);
1025
```
1026
1027
This is very useful when combined with [co](https://github.com/visionmedia/co) or [koa](https://github.com/koajs/koa), which automatically resolve promise-like objects for you.
1028
1029
```js
1030
co(function*(){
1031
  var doc = yield mquery().findOne({ _id: 499 });
1032
  console.log(doc); // { _id: 499, name: 'amazing', .. }
1033
})();
1034
```
1035
1036
_NOTE_:
1037
The returned promise is a [bluebird](https://github.com/petkaantonov/bluebird/) promise but this is customizable. If you want to
1038
use your favorite promise library, simply set `mquery.Promise = YourPromiseConstructor`.
1039
Your `Promise` must be [promises A+](http://promisesaplus.com/) compliant.
1040
1041
### thunk()
1042
1043
Returns a thunk which when called runs the query's `exec` method passing the results to the callback.
1044
1045
```js
1046
var thunk = mquery(collection).find({..}).thunk();
1047
1048
thunk(function(err, results) {
1049
1050
})
1051
```
1052
1053
### merge(object)
1054
1055
Merges other mquery or match condition objects into this one. When an mquery instance is passed, its match conditions, field selection and options are merged.
1056
1057
```js
1058
var drum = mquery({ type: 'drum' }).collection(instruments);
1059
var redDrum = mquery({ color: 'red' }).merge(drum);
1060
redDrum.count(function (err, n) {
1061
  console.log('there are %d red drums', n);
1062
})
1063
```
1064
1065
Internally uses `mquery.canMerge` to determine validity.
1066
1067
### setOptions(options)
1068
1069
Sets query options.
1070
1071
```js
1072
mquery().setOptions({ collection: coll, limit: 20 })
1073
```
1074
1075
##### options
1076
1077
- [tailable](#tailable) *
1078
- [sort](#sort) *
1079
- [limit](#limit) *
1080
- [skip](#skip) *
1081
- [maxScan](#maxscan) *
1082
- [maxTime](#maxtime) *
1083
- [batchSize](#batchSize) *
1084
- [comment](#comment) *
1085
- [snapshot](#snapshot) *
1086
- [hint](#hint) *
1087
- [slaveOk](#slaveOk) *
1088
- [safe](http://docs.mongodb.org/manual/reference/write-concern/): Boolean - passed through to the collection. Setting to `true` is equivalent to `{ w: 1 }`
1089
- [collection](#collection): the collection to query against
1090
1091
_* denotes a query helper method is also available_
1092
1093
### setTraceFunction(func)
1094
1095
Set a function to trace this query. Useful for profiling or logging.
1096
1097
```js
1098
function traceFunction (method, queryInfo, query) {
1099
  console.log('starting ' + method + ' query');
1100
1101
  return function (err, result, millis) {
1102
    console.log('finished ' + method + ' query in ' + millis + 'ms');
1103
  };
1104
}
1105
1106
mquery().setTraceFunction(traceFunction).findOne({name: 'Joe'}, cb);
1107
```
1108
1109
The trace function is passed (method, queryInfo, query)
1110
1111
- method is the name of the method being called (e.g. findOne)
1112
- queryInfo contains information about the query:
1113
 - conditions: query conditions/criteria
1114
 - options: options such as sort, fields, etc
1115
 - doc: document being updated
1116
- query is the query object
1117
1118
The trace function should return a callback function which accepts:
1119
- err: error, if any
1120
- result: result, if any
1121
- millis: time spent waiting for query result
1122
1123
NOTE: stream requests are not traced.
1124
1125
### mquery.setGlobalTraceFunction(func)
1126
1127
Similar to `setTraceFunction()` but automatically applied to all queries.
1128
1129
```js
1130
mquery.setTraceFunction(traceFunction);
1131
```
1132
1133
### mquery.canMerge(conditions)
1134
1135
Determines if `conditions` can be merged using `mquery().merge()`.
1136
1137
```js
1138
var query = mquery({ type: 'drum' });
1139
var okToMerge = mquery.canMerge(anObject)
1140
if (okToMerge) {
1141
  query.merge(anObject);
1142
}
1143
```
1144
1145
## mquery.use$geoWithin
1146
1147
MongoDB 2.4 introduced the `$geoWithin` operator which replaces and is 100% backward compatible with `$within`. As of mquery 0.2, we default to using `$geoWithin` for all `within()` calls.
1148
1149
If you are running MongoDB < 2.4 this will be problematic. To force `mquery` to be backward compatible and always use `$within`, set the `mquery.use$geoWithin` flag to `false`.
1150
1151
```js
1152
mquery.use$geoWithin = false;
1153
```
1154
1155
## Custom Base Queries
1156
1157
Often times we want custom base queries that encapsulate predefined criteria. With `mquery` this is easy. First create the query you want to reuse and call its `toConstructor()` method which returns a new subclass of `mquery` that retains all options and criteria of the original.
1158
1159
```js
1160
var greatMovies = mquery(movieCollection).where('rating').gte(4.5).toConstructor();
1161
1162
// use it!
1163
greatMovies().count(function (err, n) {
1164
  console.log('There are %d great movies', n);
1165
});
1166
1167
greatMovies().where({ name: /^Life/ }).select('name').find(function (err, docs) {
1168
  console.log(docs);
1169
});
1170
```
1171
1172
## Validation
1173
1174
Method and options combinations are checked for validity at runtime to prevent creation of invalid query constructs. For example, a `distinct` query does not support specifying options like `hint` or field selection. In this case an error will be thrown so you can catch these mistakes in development.
1175
1176
## Debug support
1177
1178
Debug mode is provided through the use of the [debug](https://github.com/visionmedia/debug) module. To enable:
1179
1180
    DEBUG=mquery node yourprogram.js
1181
1182
Read the debug module documentation for more details.
1183
1184
## General compatibility
1185
1186
#### ObjectIds
1187
1188
`mquery` clones query arguments before passing them to a `collection` method for execution.
1189
This prevents accidental side-affects to the objects you pass.
1190
To clone `ObjectIds` we need to make some assumptions.
1191
1192
First, to check if an object is an `ObjectId`, we check its constructors name. If it matches either
1193
`ObjectId` or `ObjectID` we clone it.
1194
1195
To clone `ObjectIds`, we call its optional `clone` method. If a `clone` method does not exist, we fall
1196
back to calling `new obj.constructor(obj.id)`. We assume, for compatibility with the
1197
Node.js driver, that the `ObjectId` instance has a public `id` property and that
1198
when creating an `ObjectId` instance we can pass that `id` as an argument.
1199
1200
#### Read Preferences
1201
1202
`mquery` supports specifying [Read Preferences]() to control from which MongoDB node your query will read.
1203
The Read Preferences spec also support specifying tags. To pass tags, some
1204
drivers (Node.js driver) require passing a special constructor that handles both the read preference and its tags.
1205
If you need to specify tags, pass an instance of your drivers ReadPreference constructor or roll your own. `mquery` will store whatever you provide and pass later to your collection during execution.
1206
1207
## Future goals
1208
1209
  - mongo shell compatibility
1210
  - browser compatibility
1211
1212
## Installation
1213
1214
    $ npm install mquery
1215
1216
## License
1217
1218
[MIT](https://github.com/aheckmann/mquery/blob/master/LICENSE)