1
1
const _ = require ( 'underscore' ) ;
2
2
const sanitizeParams = require ( './utils/sanitizeParams' ) ;
3
3
const { prepareResponse, generateSort, generateCursorQuery } = require ( './utils/query' ) ;
4
+ const aggregate = require ( './aggregate' ) ;
4
5
const config = require ( './config' ) ;
5
6
6
7
/**
@@ -21,6 +22,9 @@ const config = require('./config');
21
22
* 3. Immutable. If the value changes between paged queries, it could appear twice.
22
23
* The default is to use the Mongo built-in '_id' field, which satisfies the above criteria.
23
24
* The only reason to NOT use the Mongo _id field is if you chose to implement your own ids.
25
+ * -sortAscending {boolean} Whether to sort in ascending order by the `paginatedField`.
26
+ * -sortCaseInsensitive {boolean} Whether to ignore case when sorting, in which case `paginatedField`
27
+ * must be a string property.
24
28
* -next {String} The value to start querying the page.
25
29
* -previous {String} The value to start querying previous page.
26
30
* -after {String} The _id to start querying the page.
@@ -29,35 +33,45 @@ const config = require('./config');
29
33
* -collation {Object} An optional collation to provide to the mongo query. E.g. { locale: 'en', strength: 2 }. When null, disables the global collation.
30
34
*/
31
35
module . exports = async function ( collection , params ) {
32
- // Need to repeat `params.paginatedField` default value ('_id') since it's set in 'sanitizeParams()'
33
36
const removePaginatedFieldInResponse =
34
37
params . fields && ! params . fields [ params . paginatedField || '_id' ] ;
35
38
36
- params = _ . defaults ( await sanitizeParams ( collection , params ) , { query : { } } ) ;
37
- const cursorQuery = generateCursorQuery ( params ) ;
38
- const $sort = generateSort ( params ) ;
39
+ let response ;
40
+ if ( params . sortCaseInsensitive ) {
41
+ // For case-insensitive sorting, we need to work with an aggregation:
42
+ response = aggregate ( collection , {
43
+ ...params ,
44
+ aggregation : params . query ? [ { $match : params . query } ] : [ ] ,
45
+ } ) ;
46
+ } else {
47
+ // Need to repeat `params.paginatedField` default value ('_id') since it's set in 'sanitizeParams()'
48
+ params = _ . defaults ( await sanitizeParams ( collection , params ) , { query : { } } ) ;
39
49
40
- // Support both the native 'mongodb' driver and 'mongoist'. See:
41
- // https://www.npmjs.com/package/mongoist#cursor-operations
42
- const findMethod = collection . findAsCursor ? 'findAsCursor' : 'find' ;
50
+ const cursorQuery = generateCursorQuery ( params ) ;
51
+ const $sort = generateSort ( params ) ;
43
52
44
- const query = collection [ findMethod ] ( { $and : [ cursorQuery , params . query ] } , params . fields ) ;
53
+ // Support both the native 'mongodb' driver and 'mongoist'. See:
54
+ // https://www.npmjs.com/package/mongoist#cursor-operations
55
+ const findMethod = collection . findAsCursor ? 'findAsCursor' : 'find' ;
45
56
46
- /**
47
- * IMPORTANT
48
- *
49
- * If using collation, check the README:
50
- * https://github.com/mixmaxhq/mongo-cursor-pagination#important-note-regarding-collation
51
- */
52
- const isCollationNull = params . collation === null ;
53
- const collation = params . collation || config . COLLATION ;
54
- const collatedQuery = collation && ! isCollationNull ? query . collation ( collation ) : query ;
55
- // Query one more element to see if there's another page.
56
- const cursor = collatedQuery . sort ( $sort ) . limit ( params . limit + 1 ) ;
57
- if ( params . hint ) cursor . hint ( params . hint ) ;
58
- const results = await cursor . toArray ( ) ;
57
+ const query = collection [ findMethod ] ( { $and : [ cursorQuery , params . query ] } , params . fields ) ;
59
58
60
- const response = prepareResponse ( results , params ) ;
59
+ /**
60
+ * IMPORTANT
61
+ *
62
+ * If using collation, check the README:
63
+ * https://github.com/mixmaxhq/mongo-cursor-pagination#important-note-regarding-collation
64
+ */
65
+ const isCollationNull = params . collation === null ;
66
+ const collation = params . collation || config . COLLATION ;
67
+ const collatedQuery = collation && ! isCollationNull ? query . collation ( collation ) : query ;
68
+ // Query one more element to see if there's another page.
69
+ const cursor = collatedQuery . sort ( $sort ) . limit ( params . limit + 1 ) ;
70
+ if ( params . hint ) cursor . hint ( params . hint ) ;
71
+ const results = await cursor . toArray ( ) ;
72
+
73
+ response = prepareResponse ( results , params ) ;
74
+ }
61
75
62
76
// Remove fields that we added to the query (such as paginatedField and _id) that the user didn't ask for.
63
77
if ( removePaginatedFieldInResponse ) {
0 commit comments