diff --git a/src/database/mongo.js b/src/database/mongo.js index 99e045d9f4..9ab35feba2 100644 --- a/src/database/mongo.js +++ b/src/database/mongo.js @@ -98,6 +98,7 @@ mongoModule.getConnectionOptions = function () { reconnectTries: 3600, reconnectInterval: 1000, autoReconnect: true, + useNewUrlParser: true, }; return _.merge(connOptions, nconf.get('mongo:options') || {}); diff --git a/src/database/mongo/hash.js b/src/database/mongo/hash.js index bfbeb5cb6c..1298e6e292 100644 --- a/src/database/mongo/hash.js +++ b/src/database/mongo/hash.js @@ -46,7 +46,7 @@ module.exports = function (db, module) { if (data.hasOwnProperty('')) { delete data['']; } - db.collection('objects').update({ _key: key }, { $set: data }, { upsert: true, w: 1 }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $set: data }, { upsert: true, w: 1 }, function (err) { if (err) { return callback(err); } @@ -208,8 +208,8 @@ module.exports = function (db, module) { } var data = {}; field = helpers.fieldToString(field); - data[field] = ''; - db.collection('objects').findOne({ _key: key }, { fields: data }, function (err, item) { + data[field] = 1; + db.collection('objects').findOne({ _key: key }, { projection: data }, function (err, item) { callback(err, !!item && item[field] !== undefined && item[field] !== null); }); }; @@ -222,10 +222,10 @@ module.exports = function (db, module) { var data = {}; fields.forEach(function (field) { field = helpers.fieldToString(field); - data[field] = ''; + data[field] = 1; }); - db.collection('objects').findOne({ _key: key }, { fields: data }, function (err, item) { + db.collection('objects').findOne({ _key: key }, { projection: data }, function (err, item) { if (err) { return callback(err); } @@ -259,7 +259,7 @@ module.exports = function (db, module) { data[field] = ''; }); - db.collection('objects').update({ _key: key }, { $unset: data }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $unset: data }, function (err) { if (err) { return callback(err); } @@ -317,7 +317,7 @@ module.exports = function (db, module) { } - db.collection('objects').findAndModify({ _key: key }, {}, { $inc: data }, { new: true, upsert: true }, function (err, result) { + db.collection('objects').findOneAndUpdate({ _key: key }, { $inc: data }, { returnOriginal: false, upsert: true }, function (err, result) { if (err) { return callback(err); } diff --git a/src/database/mongo/list.js b/src/database/mongo/list.js index b0b87ae922..219cd53be5 100644 --- a/src/database/mongo/list.js +++ b/src/database/mongo/list.js @@ -18,7 +18,7 @@ module.exports = function (db, module) { } if (exists) { - db.collection('objects').update({ _key: key }, { $push: { array: { $each: [value], $position: 0 } } }, { upsert: true, w: 1 }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $push: { array: { $each: [value], $position: 0 } } }, { upsert: true, w: 1 }, function (err) { callback(err); }); } else { @@ -33,7 +33,7 @@ module.exports = function (db, module) { return callback(); } value = helpers.valueToString(value); - db.collection('objects').update({ _key: key }, { $push: { array: value } }, { upsert: true, w: 1 }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $push: { array: value } }, { upsert: true, w: 1 }, function (err) { callback(err); }); }; @@ -48,7 +48,7 @@ module.exports = function (db, module) { return callback(err); } - db.collection('objects').update({ _key: key }, { $pop: { array: 1 } }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $pop: { array: 1 } }, function (err) { callback(err, (value && value.length) ? value[0] : null); }); }); @@ -61,7 +61,7 @@ module.exports = function (db, module) { } value = helpers.valueToString(value); - db.collection('objects').update({ _key: key }, { $pull: { array: value } }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $pull: { array: value } }, function (err) { callback(err); }); }; @@ -76,7 +76,7 @@ module.exports = function (db, module) { return callback(err); } - db.collection('objects').update({ _key: key }, { $set: { array: value } }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $set: { array: value } }, function (err) { callback(err); }); }); diff --git a/src/database/mongo/main.js b/src/database/mongo/main.js index 55a29e6ff9..1b23bc3409 100644 --- a/src/database/mongo/main.js +++ b/src/database/mongo/main.js @@ -12,7 +12,7 @@ module.exports = function (db, module) { module.emptydb = function (callback) { callback = callback || helpers.noop; - db.collection('objects').remove({}, function (err) { + db.collection('objects').deleteMany({}, function (err) { if (err) { return callback(err); } @@ -35,7 +35,7 @@ module.exports = function (db, module) { if (!key) { return callback(); } - db.collection('objects').remove({ _key: key }, function (err) { + db.collection('objects').deleteMany({ _key: key }, function (err) { if (err) { return callback(err); } @@ -49,7 +49,7 @@ module.exports = function (db, module) { if (!Array.isArray(keys) || !keys.length) { return callback(); } - db.collection('objects').remove({ _key: { $in: keys } }, function (err) { + db.collection('objects').deleteMany({ _key: { $in: keys } }, function (err) { if (err) { return callback(err); } @@ -97,14 +97,14 @@ module.exports = function (db, module) { if (!key) { return callback(); } - db.collection('objects').findAndModify({ _key: key }, {}, { $inc: { data: 1 } }, { new: true, upsert: true }, function (err, result) { + db.collection('objects').findOneAndUpdate({ _key: key }, { $inc: { data: 1 } }, { returnOriginal: false, upsert: true }, function (err, result) { callback(err, result && result.value ? result.value.data : null); }); }; module.rename = function (oldKey, newKey, callback) { callback = callback || helpers.noop; - db.collection('objects').update({ _key: oldKey }, { $set: { _key: newKey } }, { multi: true }, function (err) { + db.collection('objects').updateMany({ _key: oldKey }, { $set: { _key: newKey } }, function (err) { if (err) { return callback(err); } diff --git a/src/database/mongo/sets.js b/src/database/mongo/sets.js index 4f807b3922..b66772639c 100644 --- a/src/database/mongo/sets.js +++ b/src/database/mongo/sets.js @@ -13,7 +13,7 @@ module.exports = function (db, module) { array[index] = helpers.valueToString(element); }); - db.collection('objects').update({ + db.collection('objects').updateOne({ _key: key, }, { $addToSet: { @@ -74,7 +74,7 @@ module.exports = function (db, module) { callback(err); }); } else { - db.collection('objects').update({ _key: key }, { $pullAll: { members: value } }, function (err) { + db.collection('objects').updateOne({ _key: key }, { $pullAll: { members: value } }, function (err) { callback(err); }); } @@ -87,7 +87,7 @@ module.exports = function (db, module) { } value = helpers.valueToString(value); - db.collection('objects').update({ _key: { $in: keys } }, { $pull: { members: value } }, { multi: true }, function (err) { + db.collection('objects').updateMany({ _key: { $in: keys } }, { $pull: { members: value } }, function (err) { callback(err); }); }; @@ -98,7 +98,7 @@ module.exports = function (db, module) { } value = helpers.valueToString(value); - db.collection('objects').findOne({ _key: key, members: value }, { _id: 0, members: 0 }, function (err, item) { + db.collection('objects').findOne({ _key: key, members: value }, { projection: { _id: 0, members: 0 } }, function (err, item) { callback(err, item !== null && item !== undefined); }); }; @@ -112,7 +112,7 @@ module.exports = function (db, module) { values[i] = helpers.valueToString(values[i]); } - db.collection('objects').findOne({ _key: key }, { _id: 0, _key: 0 }, function (err, items) { + db.collection('objects').findOne({ _key: key }, { projection: { _id: 0, _key: 0 } }, function (err, items) { if (err) { return callback(err); } @@ -131,7 +131,7 @@ module.exports = function (db, module) { } value = helpers.valueToString(value); - db.collection('objects').find({ _key: { $in: sets }, members: value }, { _id: 0, members: 0 }).toArray(function (err, result) { + db.collection('objects').find({ _key: { $in: sets }, members: value }, { projection: { _id: 0, members: 0 } }).toArray(function (err, result) { if (err) { return callback(err); } @@ -184,7 +184,7 @@ module.exports = function (db, module) { if (!key) { return callback(null, 0); } - db.collection('objects').findOne({ _key: key }, { _id: 0 }, function (err, data) { + db.collection('objects').findOne({ _key: key }, { projection: { _id: 0 } }, function (err, data) { callback(err, data ? data.members.length : 0); }); }; diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index d4eb7a8522..9ec82f5a68 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -32,9 +32,9 @@ module.exports = function (db, module) { return callback(); } - var fields = { _id: 0, value: 1 }; - if (withScores) { - fields.score = 1; + var fields = { _id: 0, _key: 0 }; + if (!withScores) { + fields.score = 0; } if (Array.isArray(key)) { @@ -62,7 +62,7 @@ module.exports = function (db, module) { limit = 0; } - db.collection('objects').find({ _key: key }, { fields: fields }) + db.collection('objects').find({ _key: key }, { projection: fields }) .limit(limit) .skip(start) .sort({ score: sort }) @@ -70,6 +70,7 @@ module.exports = function (db, module) { if (err || !data) { return callback(err); } + if (reverse) { data.reverse(); } @@ -117,12 +118,12 @@ module.exports = function (db, module) { query.score.$lte = max; } - var fields = { _id: 0, value: 1 }; - if (withScores) { - fields.score = 1; + var fields = { _id: 0, _key: 0 }; + if (!withScores) { + fields.score = 0; } - db.collection('objects').find(query, { fields: fields }) + db.collection('objects').find(query, { projection: fields }) .limit(count) .skip(start) .sort({ score: sort }) @@ -155,7 +156,7 @@ module.exports = function (db, module) { query.score.$lte = max; } - db.collection('objects').count(query, function (err, count) { + db.collection('objects').countDocuments(query, function (err, count) { callback(err, count || 0); }); }; @@ -164,7 +165,7 @@ module.exports = function (db, module) { if (!key) { return callback(null, 0); } - db.collection('objects').count({ _key: key }, function (err, count) { + db.collection('objects').countDocuments({ _key: key }, function (err, count) { count = parseInt(count, 10); callback(err, count || 0); }); @@ -220,7 +221,7 @@ module.exports = function (db, module) { return callback(err, null); } - db.collection('objects').count({ + db.collection('objects').countDocuments({ $or: [ { _key: key, @@ -273,7 +274,7 @@ module.exports = function (db, module) { return callback(null, null); } value = helpers.valueToString(value); - db.collection('objects').findOne({ _key: key, value: value }, { fields: { _id: 0, score: 1 } }, function (err, result) { + db.collection('objects').findOne({ _key: key, value: value }, { projection: { _id: 0, _key: 0, value: 0 } }, function (err, result) { callback(err, result ? result.score : null); }); }; @@ -283,7 +284,7 @@ module.exports = function (db, module) { return callback(); } value = helpers.valueToString(value); - db.collection('objects').find({ _key: { $in: keys }, value: value }, { _id: 0, _key: 1, score: 1 }).toArray(function (err, result) { + db.collection('objects').find({ _key: { $in: keys }, value: value }, { projection: { _id: 0, value: 0 } }).toArray(function (err, result) { if (err) { return callback(err); } @@ -306,7 +307,7 @@ module.exports = function (db, module) { return callback(null, null); } values = values.map(helpers.valueToString); - db.collection('objects').find({ _key: key, value: { $in: values } }, { _id: 0, value: 1, score: 1 }).toArray(function (err, result) { + db.collection('objects').find({ _key: key, value: { $in: values } }, { projection: { _id: 0, _key: 0 } }).toArray(function (err, result) { if (err) { return callback(err); } @@ -333,7 +334,7 @@ module.exports = function (db, module) { return callback(); } value = helpers.valueToString(value); - db.collection('objects').findOne({ _key: key, value: value }, { _id: 0, value: 1 }, function (err, result) { + db.collection('objects').findOne({ _key: key, value: value }, { projection: { _id: 0, _key: 0, score: 0 } }, function (err, result) { callback(err, !!result); }); }; @@ -343,17 +344,19 @@ module.exports = function (db, module) { return callback(); } values = values.map(helpers.valueToString); - db.collection('objects').find({ _key: key, value: { $in: values } }, { fields: { _id: 0, value: 1 } }).toArray(function (err, results) { + db.collection('objects').find({ _key: key, value: { $in: values } }, { projection: { _id: 0, _key: 0, score: 0 } }).toArray(function (err, results) { if (err) { return callback(err); } - - results = results.map(function (item) { - return item.value; + var isMember = {}; + results.forEach(function (item) { + if (item) { + isMember[item.value] = true; + } }); values = values.map(function (value) { - return results.indexOf(value) !== -1; + return !!isMember[value]; }); callback(null, values); }); @@ -364,17 +367,19 @@ module.exports = function (db, module) { return callback(); } value = helpers.valueToString(value); - db.collection('objects').find({ _key: { $in: keys }, value: value }, { fields: { _id: 0, _key: 1, value: 1 } }).toArray(function (err, results) { + db.collection('objects').find({ _key: { $in: keys }, value: value }, { projection: { _id: 0, score: 0 } }).toArray(function (err, results) { if (err) { return callback(err); } - - results = results.map(function (item) { - return item._key; + var isMember = {}; + results.forEach(function (item) { + if (item) { + isMember[item._key] = true; + } }); results = keys.map(function (key) { - return results.indexOf(key) !== -1; + return !!isMember[key]; }); callback(null, results); }); @@ -384,7 +389,7 @@ module.exports = function (db, module) { if (!Array.isArray(keys) || !keys.length) { return callback(null, []); } - db.collection('objects').find({ _key: { $in: keys } }, { _id: 0, _key: 1, value: 1 }).sort({ score: 1 }).toArray(function (err, data) { + db.collection('objects').find({ _key: { $in: keys } }, { projection: { _id: 0, score: 0 } }).sort({ score: 1 }).toArray(function (err, data) { if (err) { return callback(err); } @@ -412,7 +417,7 @@ module.exports = function (db, module) { value = helpers.valueToString(value); data.score = parseFloat(increment); - db.collection('objects').findAndModify({ _key: key, value: value }, {}, { $inc: data }, { new: true, upsert: true }, function (err, result) { + db.collection('objects').findOneAndUpdate({ _key: key, value: value }, { $inc: data }, { returnOriginal: false, upsert: true }, function (err, result) { // if there is duplicate key error retry the upsert // https://github.com/NodeBB/NodeBB/issues/4467 // https://jira.mongodb.org/browse/SERVER-14322 @@ -448,7 +453,7 @@ module.exports = function (db, module) { var query = { _key: key }; buildLexQuery(query, min, max); - db.collection('objects').find(query, { _id: 0, value: 1 }) + db.collection('objects').find(query, { projection: { _id: 0, _key: 0, score: 0 } }) .sort({ value: sort }) .skip(start) .limit(count === -1 ? 0 : count) @@ -469,7 +474,7 @@ module.exports = function (db, module) { var query = { _key: key }; buildLexQuery(query, min, max); - db.collection('objects').remove(query, function (err) { + db.collection('objects').deleteMany(query, function (err) { callback(err); }); }; @@ -499,13 +504,12 @@ module.exports = function (db, module) { module.processSortedSet = function (setKey, processFn, options, callback) { var done = false; var ids = []; - var project = { _id: 0, value: 1 }; - if (options.withScores) { - project.score = 1; + var project = { _id: 0, _key: 0 }; + if (!options.withScores) { + project.score = 0; } - var cursor = db.collection('objects').find({ _key: setKey }) + var cursor = db.collection('objects').find({ _key: setKey }, { projection: project }) .sort({ score: 1 }) - .project(project) .batchSize(options.batch); async.whilst( diff --git a/src/database/mongo/sorted/add.js b/src/database/mongo/sorted/add.js index b90501feee..e71bb0568a 100644 --- a/src/database/mongo/sorted/add.js +++ b/src/database/mongo/sorted/add.js @@ -14,7 +14,7 @@ module.exports = function (db, module) { value = helpers.valueToString(value); - db.collection('objects').update({ _key: key, value: value }, { $set: { score: parseFloat(score) } }, { upsert: true, w: 1 }, function (err) { + db.collection('objects').updateOne({ _key: key, value: value }, { $set: { score: parseFloat(score) } }, { upsert: true, w: 1 }, function (err) { if (err && err.message.startsWith('E11000 duplicate key error')) { return process.nextTick(module.sortedSetAdd, key, score, value, callback); } diff --git a/src/database/mongo/sorted/remove.js b/src/database/mongo/sorted/remove.js index c9bf121e10..80f9221604 100644 --- a/src/database/mongo/sorted/remove.js +++ b/src/database/mongo/sorted/remove.js @@ -12,16 +12,16 @@ module.exports = function (db, module) { return callback(); } if (Array.isArray(key) && Array.isArray(value)) { - db.collection('objects').remove({ _key: { $in: key }, value: { $in: value } }, done); + db.collection('objects').deleteMany({ _key: { $in: key }, value: { $in: value } }, done); } else if (Array.isArray(value)) { value = value.map(helpers.valueToString); - db.collection('objects').remove({ _key: key, value: { $in: value } }, done); + db.collection('objects').deleteMany({ _key: key, value: { $in: value } }, done); } else if (Array.isArray(key)) { value = helpers.valueToString(value); - db.collection('objects').remove({ _key: { $in: key }, value: value }, done); + db.collection('objects').deleteMany({ _key: { $in: key }, value: value }, done); } else { value = helpers.valueToString(value); - db.collection('objects').remove({ _key: key, value: value }, done); + db.collection('objects').deleteOne({ _key: key, value: value }, done); } }; @@ -32,7 +32,7 @@ module.exports = function (db, module) { } value = helpers.valueToString(value); - db.collection('objects').remove({ _key: { $in: keys }, value: value }, function (err) { + db.collection('objects').deleteMany({ _key: { $in: keys }, value: value }, function (err) { callback(err); }); }; @@ -52,7 +52,7 @@ module.exports = function (db, module) { query.score.$lte = parseFloat(max); } - db.collection('objects').remove(query, function (err) { + db.collection('objects').deleteMany(query, function (err) { callback(err); }); }; diff --git a/src/upgrades/1.7.3/key_value_schema_change.js b/src/upgrades/1.7.3/key_value_schema_change.js index a8abefb10a..882f8ff200 100644 --- a/src/upgrades/1.7.3/key_value_schema_change.js +++ b/src/upgrades/1.7.3/key_value_schema_change.js @@ -23,7 +23,7 @@ module.exports = { var cursor; async.waterfall([ function (next) { - client.collection('objects').count({ + client.collection('objects').countDocuments({ _key: { $exists: true }, value: { $exists: true }, score: { $exists: false }, @@ -55,7 +55,7 @@ module.exports = { } delete item.expireAt; if (Object.keys(item).length === 3 && item.hasOwnProperty('_key') && item.hasOwnProperty('value')) { - client.collection('objects').update({ _key: item._key }, { $rename: { value: 'data' } }, next); + client.collection('objects').updateOne({ _key: item._key }, { $rename: { value: 'data' } }, next); } else { next(); } diff --git a/test/database/keys.js b/test/database/keys.js index 6b187b4e3d..1051658b26 100644 --- a/test/database/keys.js +++ b/test/database/keys.js @@ -192,6 +192,24 @@ describe('Key methods', function () { }); }); }); + + it('should rename multiple keys', function (done) { + db.sortedSetAdd('zsettorename', [1, 2, 3], ['value1', 'value2', 'value3'], function (err) { + assert.ifError(err); + db.rename('zsettorename', 'newzsetname', function (err) { + assert.ifError(err); + db.exists('zsettorename', function (err, exists) { + assert.ifError(err); + assert(!exists); + db.getSortedSetRange('newzsetname', 0, -1, function (err, values) { + assert.ifError(err); + assert.deepEqual(['value1', 'value2', 'value3'], values); + done(); + }); + }); + }); + }); + }); }); describe('type', function () {