diff options
author | David Storch <david.storch@10gen.com> | 2016-04-25 17:55:54 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2016-05-10 09:16:34 -0400 |
commit | 6218a59683bf97c6cb7f198f9d9eccc0371f8bb7 (patch) | |
tree | ea0558dec72853193d406a0eb2942fff850c4f57 /src | |
parent | e381d56bfe3a805e44678566437ef4a732d3fa1a (diff) | |
download | mongo-6218a59683bf97c6cb7f198f9d9eccc0371f8bb7.tar.gz |
SERVER-23791 extend shell helpers to pass collation parameter to server
Includes changes to the following:
- Bulk API
- CRUD API
- DBCollection CRUD methods (e.g. DBCollection.prototype.remove())
- New DBQuery.prototype.collation() method to use with find().
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/shell/bulk_api.js | 37 | ||||
-rw-r--r-- | src/mongo/shell/collection.js | 44 | ||||
-rw-r--r-- | src/mongo/shell/crud_api.js | 86 | ||||
-rw-r--r-- | src/mongo/shell/explain_query.js | 2 | ||||
-rw-r--r-- | src/mongo/shell/explainable.js | 18 | ||||
-rw-r--r-- | src/mongo/shell/query.js | 16 |
6 files changed, 185 insertions, 18 deletions
diff --git a/src/mongo/shell/bulk_api.js b/src/mongo/shell/bulk_api.js index 84dc583b1ea..8ef10b5c976 100644 --- a/src/mongo/shell/bulk_api.js +++ b/src/mongo/shell/bulk_api.js @@ -674,6 +674,11 @@ var _bulk_api_module = (function() { upsert: upsert }; + // Copy over the collation, if we have one. + if (currentOp.hasOwnProperty('collation')) { + document.collation = currentOp.collation; + } + // Clear out current Op currentOp = null; // Add the update document to the list @@ -693,6 +698,11 @@ var _bulk_api_module = (function() { upsert: upsert }; + // Copy over the collation, if we have one. + if (currentOp.hasOwnProperty('collation')) { + document.collation = currentOp.collation; + } + // Clear out current Op currentOp = null; // Add the update document to the list @@ -718,6 +728,11 @@ var _bulk_api_module = (function() { limit: 1 }; + // Copy over the collation, if we have one. + if (currentOp.hasOwnProperty('collation')) { + document.collation = currentOp.collation; + } + // Clear out current Op currentOp = null; // Add the remove document to the list @@ -733,11 +748,31 @@ var _bulk_api_module = (function() { limit: 0 }; + // Copy over the collation, if we have one. + if (currentOp.hasOwnProperty('collation')) { + document.collation = currentOp.collation; + } + // Clear out current Op currentOp = null; // Add the remove document to the list return addToOperationsList(REMOVE, document); - } + }, + + collation: function(collationSpec) { + if (!collection.getMongo().hasWriteCommands()) { + throw new Error( + "cannot use collation if server does not support write commands"); + } + + if (collection.getMongo().writeMode() !== "commands") { + throw new Error("write mode must be 'commands' in order to use collation, " + + "but found write mode: " + collection.getMongo().writeMode()); + } + + currentOp.collation = collationSpec; + return findOperations; + }, }; // diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index c066648be4a..72efdbaaf97 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -279,13 +279,17 @@ DBCollection.prototype.find = function(query, fields, limit, skip, batchSize, op return cursor; }; -DBCollection.prototype.findOne = function(query, fields, options, readConcern) { +DBCollection.prototype.findOne = function(query, fields, options, readConcern, collation) { var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/, 0 /* batchSize */, options); if (readConcern) { cursor = cursor.readConcern(readConcern); } + if (collation) { + cursor = cursor.collation(collation); + } + if (!cursor.hasNext()) return null; var ret = cursor.next(); @@ -408,10 +412,12 @@ DBCollection.prototype._parseRemove = function(t, justOne) { var query = this._massageObject(t); var wc = undefined; + var collation = undefined; if (typeof(justOne) === "object") { var opts = justOne; wc = opts.writeConcern; justOne = opts.justOne; + collation = opts.collation; } // Normalize "justOne" to a bool. @@ -425,7 +431,8 @@ DBCollection.prototype._parseRemove = function(t, justOne) { return { "query": query, "justOne": justOne, - "wc": wc + "wc": wc, + "collation": collation }; }; @@ -434,6 +441,7 @@ DBCollection.prototype.remove = function(t, justOne) { var query = parsed.query; var justOne = parsed.justOne; var wc = parsed.wc; + var collation = parsed.collation; var result = undefined; var startTime = @@ -443,6 +451,10 @@ DBCollection.prototype.remove = function(t, justOne) { var bulk = this.initializeOrderedBulkOp(); var removeOp = bulk.find(query); + if (collation) { + removeOp.collation(collation); + } + if (justOne) { removeOp.removeOne(); } else { @@ -460,6 +472,10 @@ DBCollection.prototype.remove = function(t, justOne) { } } } else { + if (collation) { + throw new Error("collation requires use of write commands"); + } + this._validateRemoveDoc(t); this.getMongo().remove(this._fullName, query, justOne); @@ -505,6 +521,7 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) { throw Error("need an object"); var wc = undefined; + var collation = undefined; // can pass options via object for improved readability if (typeof(upsert) === "object") { if (multi) { @@ -516,6 +533,7 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) { multi = opts.multi; wc = opts.writeConcern; upsert = opts.upsert; + collation = opts.collation; } // Normalize 'upsert' and 'multi' to booleans. @@ -531,7 +549,8 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) { "obj": obj, "upsert": upsert, "multi": multi, - "wc": wc + "wc": wc, + "collation": collation }; }; @@ -542,6 +561,7 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) { var upsert = parsed.upsert; var multi = parsed.multi; var wc = parsed.wc; + var collation = parsed.collation; var result = undefined; var startTime = @@ -555,6 +575,10 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) { updateOp = updateOp.upsert(); } + if (collation) { + updateOp.collation(collation); + } + if (multi) { updateOp.update(obj); } else { @@ -572,6 +596,10 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) { } } } else { + if (collation) { + throw new Error("collation requires use of write commands"); + } + this._validateUpdateDoc(obj); this.getMongo().update(this._fullName, query, obj, upsert, multi); @@ -1684,6 +1712,8 @@ DBCollection.prototype.unsetWriteConcern = function() { * @param {string|object} [options.hint=null] An index name hint or specification for the query. * @param {number} [options.maxTimeMS=null] The maximum amount of time to allow the query to run. * @param {string} [options.readConcern=null] The level of readConcern passed to the count command +* @param {object} [options.collation=null] The collation that should be used for string comparisons +* for this count op. * @return {number} */ DBCollection.prototype.count = function(query, options) { @@ -1710,6 +1740,10 @@ DBCollection.prototype.count = function(query, options) { query.readConcern(opts.readConcern); } + if (typeof opts.collation == 'object') { + query.collation(opts.collation); + } + // Return the result of the find return query.count(true); }; @@ -1753,6 +1787,10 @@ DBCollection.prototype.distinct = function(keyString, query, options) { cmd.maxTimeMS = opts.maxTimeMS; } + if (opts.collation) { + cmd.collation = opts.collation; + } + // Execute distinct command var res = this.runReadCommand(cmd); if (!res.ok) { diff --git a/src/mongo/shell/crud_api.js b/src/mongo/shell/crud_api.js index 7c83b5093aa..9a2d74ab62c 100644 --- a/src/mongo/shell/crud_api.js +++ b/src/mongo/shell/crud_api.js @@ -48,15 +48,15 @@ DBCollection.prototype.addIdIfNeeded = function(obj) { * * { insertOne: { document: { a: 1 } } } * -* { updateOne: { filter: {a:2}, update: {$set: {a:2}}, upsert:true } } +* { updateOne: { filter: {a:2}, update: {$set: {a:2}}, upsert:true, collation: {locale: "fr"} } } * -* { updateMany: { filter: {a:2}, update: {$set: {a:2}}, upsert:true } } +* { updateMany: { filter: {a:2}, update: {$set: {a:2}}, upsert:true collation: {locale: "fr"} } } * -* { deleteOne: { filter: {c:1} } } +* { deleteOne: { filter: {c:1}, collation: {locale: "fr"} } } * -* { deleteMany: { filter: {c:1} } } +* { deleteMany: { filter: {c:1}, collation: {locale: "fr"} } } * -* { replaceOne: { filter: {c:3}, replacement: {c:4}, upsert:true}} +* { replaceOne: { filter: {c:3}, replacement: {c:4}, upsert:true, collation: {locale: "fr"} } } * * @method * @param {object[]} operations Bulk operations to perform. @@ -112,6 +112,10 @@ DBCollection.prototype.bulkWrite = function(operations, options) { operation = operation.upsert(); } + if (op.updateOne.collation) { + operation.collation(op.updateOne.collation); + } + operation.updateOne(op.updateOne.update); } else if (op.updateMany) { if (!op.updateMany.filter) { @@ -128,6 +132,10 @@ DBCollection.prototype.bulkWrite = function(operations, options) { operation = operation.upsert(); } + if (op.updateMany.collation) { + operation.collation(op.updateMany.collation); + } + operation.update(op.updateMany.update); } else if (op.replaceOne) { if (!op.replaceOne.filter) { @@ -144,21 +152,37 @@ DBCollection.prototype.bulkWrite = function(operations, options) { operation = operation.upsert(); } + if (op.replaceOne.collation) { + operation.collation(op.replaceOne.collation); + } + operation.replaceOne(op.replaceOne.replacement); } else if (op.deleteOne) { if (!op.deleteOne.filter) { throw new Error('deleteOne bulkWrite operation expects the filter field'); } - // Translate operation to bulkOp operation - bulkOp.find(op.deleteOne.filter).removeOne(); + // Translate operation to bulkOp operation. + var deleteOp = bulkOp.find(op.deleteOne.filter); + + if (op.deleteOne.collation) { + deleteOp.collation(op.deleteOne.collation); + } + + deleteOp.removeOne(); } else if (op.deleteMany) { if (!op.deleteMany.filter) { throw new Error('deleteMany bulkWrite operation expects the filter field'); } - // Translate operation to bulkOp operation - bulkOp.find(op.deleteMany.filter).remove(); + // Translate operation to bulkOp operation. + var deleteOp = bulkOp.find(op.deleteMany.filter); + + if (op.deleteMany.collation) { + deleteOp.collation(op.deleteMany.collation); + } + + deleteOp.remove(); } }, this); @@ -317,9 +341,15 @@ DBCollection.prototype.deleteOne = function(filter, options) { // Use bulk operation API already in the shell var bulk = this.initializeOrderedBulkOp(); + var removeOp = bulk.find(filter); - // Add the deleteOne operation - bulk.find(filter).removeOne(); + // Add the collation, if there is one. + if (opts.collation) { + removeOp.collation(opts.collation); + } + + // Add the deleteOne operation. + removeOp.removeOne(); try { // Remove the first document that matches the selector @@ -368,9 +398,15 @@ DBCollection.prototype.deleteMany = function(filter, options) { // Use bulk operation API already in the shell var bulk = this.initializeOrderedBulkOp(); + var removeOp = bulk.find(filter); - // Add the deleteOne operation - bulk.find(filter).remove(); + // Add the collation, if there is one. + if (opts.collation) { + removeOp.collation(opts.collation); + } + + // Add the deleteOne operation. + removeOp.remove(); try { // Remove all documents that matche the selector @@ -435,6 +471,10 @@ DBCollection.prototype.replaceOne = function(filter, replacement, options) { op = op.upsert(); } + if (opts.collation) { + op.collation(opts.collation); + } + op.replaceOne(replacement); try { @@ -510,6 +550,10 @@ DBCollection.prototype.updateOne = function(filter, update, options) { op = op.upsert(); } + if (opts.collation) { + op.collation(opts.collation); + } + op.updateOne(update); try { @@ -585,6 +629,10 @@ DBCollection.prototype.updateMany = function(filter, update, options) { op = op.upsert(); } + if (opts.collation) { + op.collation(opts.collation); + } + op.update(update); try { @@ -649,6 +697,10 @@ DBCollection.prototype.findOneAndDelete = function(filter, options) { cmd.maxTimeMS = opts.maxTimeMS; } + if (opts.collation) { + cmd.collation = opts.collation; + } + // Get the write concern var writeConcern = this._createWriteConcern(opts); @@ -705,6 +757,10 @@ DBCollection.prototype.findOneAndReplace = function(filter, replacement, options cmd.maxTimeMS = opts.maxTimeMS; } + if (opts.collation) { + cmd.collation = opts.collation; + } + // Set flags cmd.upsert = (typeof opts.upsert == 'boolean') ? opts.upsert : false; cmd.new = (typeof opts.returnNewDocument == 'boolean') ? opts.returnNewDocument : false; @@ -769,6 +825,10 @@ DBCollection.prototype.findOneAndUpdate = function(filter, update, options) { cmd.maxTimeMS = opts.maxTimeMS; } + if (opts.collation) { + cmd.collation = opts.collation; + } + // Set flags cmd.upsert = (typeof opts.upsert == 'boolean') ? opts.upsert : false; cmd.new = (typeof opts.returnNewDocument == 'boolean') ? opts.returnNewDocument : false; diff --git a/src/mongo/shell/explain_query.js b/src/mongo/shell/explain_query.js index 3a90e17d4eb..cb14b71f0cf 100644 --- a/src/mongo/shell/explain_query.js +++ b/src/mongo/shell/explain_query.js @@ -96,6 +96,7 @@ var DBExplainQuery = (function() { var delegationFuncNames = [ "addOption", "batchSize", + "collation", "comment", "hint", "limit", @@ -226,6 +227,7 @@ var DBExplainQuery = (function() { print("\t.addOption(n)"); print("\t.batchSize(n)"); print("\t.comment(comment)"); + print("\t.collation(collationSpec)"); print("\t.count()"); print("\t.hint(hintSpec)"); print("\t.limit(n)"); diff --git a/src/mongo/shell/explainable.js b/src/mongo/shell/explainable.js index 5a6d4932c40..4f54694acd3 100644 --- a/src/mongo/shell/explainable.js +++ b/src/mongo/shell/explainable.js @@ -147,12 +147,17 @@ var Explainable = (function() { return throwOrReturn(explainResult); }; - this.distinct = function(keyString, query) { + this.distinct = function(keyString, query, options) { var distinctCmd = { distinct: this._collection.getName(), key: keyString, query: query || {} }; + + if (options && options.hasOwnProperty("collation")) { + distinctCmd.collation = options.collation; + } + var explainCmd = { explain: distinctCmd, verbosity: this._verbosity @@ -165,9 +170,15 @@ var Explainable = (function() { var parsed = this._collection._parseRemove.apply(this._collection, arguments); var query = parsed.query; var justOne = parsed.justOne; + var collation = parsed.collation; var bulk = this._collection.initializeOrderedBulkOp(); var removeOp = bulk.find(query); + + if (collation) { + removeOp.collation(collation); + } + if (justOne) { removeOp.removeOne(); } else { @@ -185,6 +196,7 @@ var Explainable = (function() { var obj = parsed.obj; var upsert = parsed.upsert; var multi = parsed.multi; + var collation = parsed.collation; var bulk = this._collection.initializeOrderedBulkOp(); var updateOp = bulk.find(query); @@ -193,6 +205,10 @@ var Explainable = (function() { updateOp = updateOp.upsert(); } + if (collation) { + updateOp.collation(collation); + } + if (multi) { updateOp.update(obj); } else { diff --git a/src/mongo/shell/query.js b/src/mongo/shell/query.js index b92f3b1f318..813d9be9e59 100644 --- a/src/mongo/shell/query.js +++ b/src/mongo/shell/query.js @@ -29,6 +29,7 @@ DBQuery.prototype.help = function() { print("\t.limit(<n>)"); print("\t.skip(<n>)"); print("\t.batchSize(<n>) - sets the number of docs to return per getMore"); + print("\t.collation({...})"); print("\t.hint({...})"); print("\t.readConcern(<level>)"); print("\t.readPref(<mode>, <tagset>)"); @@ -121,6 +122,10 @@ DBQuery.prototype._exec = function() { throw new Error("readConcern requires use of read commands"); } + if (this._special && this._query.collation) { + throw new Error("collation requires use of read commands"); + } + this._cursor = this._mongo.find(this._ns, this._query, this._fields, @@ -223,6 +228,10 @@ DBQuery.prototype._convertToCommand = function(canAttachReadPref) { cmd["readConcern"] = this._query.readConcern; } + if ("collation" in this._query) { + cmd["collation"] = this._query.collation; + } + if ((this._options & DBQuery.Option.tailable) != 0) { cmd["tailable"] = true; } @@ -350,6 +359,9 @@ DBQuery.prototype._convertToCountCmd = function(applySkipLimit) { if (this._query.readConcern) { cmd.readConcern = this._query.readConcern; } + if (this._query.collation) { + cmd.collation = this._query.collation; + } } else { cmd.query = this._query; } @@ -467,6 +479,10 @@ DBQuery.prototype.readConcern = function(level) { return this._addSpecial("readConcern", readConcernObj); }; +DBQuery.prototype.collation = function(collationSpec) { + return this._addSpecial("collation", collationSpec); +}; + /** * Sets the read preference for this cursor. * |