mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-18 10:30:49 +01:00
perf: make a single round trip for set(s)Remove
use bulkWrite
This commit is contained in:
@@ -94,44 +94,31 @@ module.exports = function (module) {
|
||||
};
|
||||
|
||||
module.setRemove = async function (key, value) {
|
||||
if (!Array.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
|
||||
value = value.map(v => helpers.valueToString(v));
|
||||
|
||||
const coll = module.client.collection('objects');
|
||||
await coll.updateMany({
|
||||
_key: Array.isArray(key) ? { $in: key } : key,
|
||||
}, {
|
||||
$pullAll: { members: value },
|
||||
});
|
||||
|
||||
await coll.deleteMany({
|
||||
_key: Array.isArray(key) ? { $in: key } : key,
|
||||
members: { $size: 0 },
|
||||
});
|
||||
await bulkSetRemove(key, value);
|
||||
};
|
||||
|
||||
module.setsRemove = async function (keys, value) {
|
||||
if (!Array.isArray(keys) || !keys.length) {
|
||||
return;
|
||||
}
|
||||
value = helpers.valueToString(value);
|
||||
|
||||
const coll = module.client.collection('objects');
|
||||
await coll.updateMany({
|
||||
_key: { $in: keys },
|
||||
}, {
|
||||
$pull: { members: value },
|
||||
});
|
||||
|
||||
await coll.deleteMany({
|
||||
_key: { $in: keys },
|
||||
members: { $size: 0 },
|
||||
});
|
||||
await bulkSetRemove(keys, value);
|
||||
};
|
||||
|
||||
async function bulkSetRemove(key, values) {
|
||||
const isKeyArray = Array.isArray(key);
|
||||
if (!key || (isKeyArray && !key.length)) return;
|
||||
|
||||
const filterKey = isKeyArray ? { $in: key } : key;
|
||||
const update = Array.isArray(values) ?
|
||||
{ $pullAll: { members: values.map(helpers.valueToString) } } :
|
||||
{ $pull: { members: helpers.valueToString(values) } };
|
||||
|
||||
await module.client.collection('objects').bulkWrite([
|
||||
{ updateMany: { filter: { _key: filterKey }, update: update } },
|
||||
{ deleteMany: { filter: { _key: filterKey, members: { $size: 0 } } } },
|
||||
], { ordered: true });
|
||||
}
|
||||
|
||||
module.isSetMember = async function (key, value) {
|
||||
if (!key) {
|
||||
return false;
|
||||
|
||||
@@ -57,6 +57,9 @@ module.exports = function (module) {
|
||||
};
|
||||
|
||||
module.setsRemove = async function (keys, value) {
|
||||
if (!Array.isArray(keys) || !keys.length) {
|
||||
return;
|
||||
}
|
||||
const batch = module.client.batch();
|
||||
keys.forEach(k => batch.sRem(String(k), String(value)));
|
||||
await helpers.execBatch(batch);
|
||||
|
||||
@@ -278,20 +278,21 @@ describe('Set methods', () => {
|
||||
});
|
||||
|
||||
describe('setsRemove()', () => {
|
||||
before((done) => {
|
||||
db.setsAdd(['set1', 'set2'], 'value', done);
|
||||
it('should remove a element from multiple sets', async () => {
|
||||
await db.setsAdd(['set1', 'set2'], 'value');
|
||||
await db.setRemove(['set1', 'set2'], 'value');
|
||||
const members = await db.isMemberOfSets(['set1', 'set2'], 'value');
|
||||
assert.deepStrictEqual(members, [false, false]);
|
||||
});
|
||||
|
||||
it('should remove a element from multiple sets', (done) => {
|
||||
db.setsRemove(['set1', 'set2'], 'value', function (err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
db.isMemberOfSets(['set1', 'set2'], 'value', (err, members) => {
|
||||
assert.equal(err, null);
|
||||
assert.deepEqual(members, [false, false]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should remove the sets if they are empty', async () => {
|
||||
await db.setAdd('setsRemoveSet3', ['a']);
|
||||
await db.setAdd('setsRemoveSet4', ['a']);
|
||||
await db.setsRemove(['setsRemoveSet3', 'setsRemoveSet4'], 'a');
|
||||
assert.deepStrictEqual(
|
||||
await db.exists(['setsRemoveSet3', 'setsRemoveSet4']),
|
||||
[false, false]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user