mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-30 10:35:55 +01:00
feat: fullname search (#8641)
* feat: fullname search * fix: take last element * fix: attempt to fix psql like query * feat: upgrade sript, another fix attempt * fix: psql test * fix: psql scan * feat: add debug for test * feat: test collate * feat: cleanup * fix: upgrade script
This commit is contained in:
committed by
GitHub
parent
9389749b79
commit
4be693f2e7
@@ -42,7 +42,7 @@ usersController.search = async function (req, res) {
|
||||
match: query,
|
||||
limit: hardCap,
|
||||
});
|
||||
return data.map(data => data.split(':')[1]);
|
||||
return data.map(data => data.split(':').pop());
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -582,15 +582,15 @@ DELETE FROM "legacy_zset" z
|
||||
if (min.match(/^\(/)) {
|
||||
q.values.push(min.substr(1));
|
||||
q.suffix += 'GT';
|
||||
q.where += ` AND z."value" > $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" > $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
} else if (min.match(/^\[/)) {
|
||||
q.values.push(min.substr(1));
|
||||
q.suffix += 'GE';
|
||||
q.where += ` AND z."value" >= $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" >= $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
} else {
|
||||
q.values.push(min);
|
||||
q.suffix += 'GE';
|
||||
q.where += ` AND z."value" >= $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" >= $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,15 +598,15 @@ DELETE FROM "legacy_zset" z
|
||||
if (max.match(/^\(/)) {
|
||||
q.values.push(max.substr(1));
|
||||
q.suffix += 'LT';
|
||||
q.where += ` AND z."value" < $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" < $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
} else if (max.match(/^\[/)) {
|
||||
q.values.push(max.substr(1));
|
||||
q.suffix += 'LE';
|
||||
q.where += ` AND z."value" <= $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" <= $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
} else {
|
||||
q.values.push(max);
|
||||
q.suffix += 'LE';
|
||||
q.where += ` AND z."value" <= $` + q.values.length + `::TEXT`;
|
||||
q.where += ` AND z."value" <= $` + q.values.length + `::TEXT COLLATE "C"`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
src/upgrades/1.15.0/fullname_search_set.js
Normal file
26
src/upgrades/1.15.0/fullname_search_set.js
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const db = require('../../database');
|
||||
|
||||
const batch = require('../../batch');
|
||||
const user = require('../../user');
|
||||
|
||||
module.exports = {
|
||||
name: 'Create fullname search set',
|
||||
timestamp: Date.UTC(2020, 8, 11),
|
||||
method: async function () {
|
||||
const progress = this.progress;
|
||||
|
||||
await batch.processSortedSet('users:joindate', async function (uids) {
|
||||
progress.incr(uids.length);
|
||||
const userData = await user.getUsersFields(uids, ['uid', 'fullname']);
|
||||
const bulkAdd = userData
|
||||
.filter(u => u.uid && u.fullname)
|
||||
.map(u => ['fullname:sorted', 0, u.fullname.toLowerCase() + ':' + u.uid]);
|
||||
await db.sortedSetAddBulk(bulkAdd);
|
||||
}, {
|
||||
batch: 500,
|
||||
progress: this.progress,
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -94,6 +94,10 @@ module.exports = function (User) {
|
||||
bulkAdd.push(['user:' + userData.uid + ':emails', timestamp, userData.email + ':' + timestamp]);
|
||||
}
|
||||
|
||||
if (userData.fullname) {
|
||||
bulkAdd.push(['fullname:sorted', 0, userData.fullname.toLowerCase() + ':' + userData.uid]);
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
db.incrObjectField('global', 'userCount'),
|
||||
db.sortedSetAddBulk(bulkAdd),
|
||||
|
||||
@@ -136,6 +136,10 @@ module.exports = function (User) {
|
||||
bulkRemove.push(['email:sorted', userData.email.toLowerCase() + ':' + uid]);
|
||||
}
|
||||
|
||||
if (userData.fullname) {
|
||||
bulkRemove.push(['fullname:sorted', userData.fullname.toLowerCase() + ':' + uid]);
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
db.sortedSetRemoveBulk(bulkRemove),
|
||||
db.decrObjectField('global', 'userCount'),
|
||||
|
||||
@@ -263,6 +263,14 @@ module.exports = function (User) {
|
||||
async function updateFullname(uid, newFullname) {
|
||||
const fullname = await User.getUserField(uid, 'fullname');
|
||||
await updateUidMapping('fullname', uid, newFullname, fullname);
|
||||
if (newFullname !== fullname) {
|
||||
if (fullname) {
|
||||
await db.sortedSetRemove('fullname:sorted', fullname.toLowerCase() + ':' + uid);
|
||||
}
|
||||
if (newFullname) {
|
||||
await db.sortedSetAdd('fullname:sorted', 0, newFullname.toLowerCase() + ':' + uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
User.changePassword = async function (uid, data) {
|
||||
|
||||
@@ -63,7 +63,7 @@ module.exports = function (User) {
|
||||
hardCap = hardCap || resultsPerPage * 10;
|
||||
|
||||
const data = await db.getSortedSetRangeByLex(searchBy + ':sorted', min, max, 0, hardCap);
|
||||
const uids = data.map(data => data.split(':')[1]);
|
||||
const uids = data.map(data => data.split(':').pop());
|
||||
return uids;
|
||||
}
|
||||
|
||||
|
||||
16
test/user.js
16
test/user.js
@@ -399,6 +399,22 @@ describe('User', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should search users by fullname', async function () {
|
||||
const uid = await User.create({ username: 'fullnamesearch1', fullname: 'Mr. Fullname' });
|
||||
const data = await socketUser.search({ uid: adminUid }, { query: 'mr', searchBy: 'fullname' });
|
||||
assert(Array.isArray(data.users));
|
||||
assert.equal(data.users.length, 1);
|
||||
assert.equal(uid, data.users[0].uid);
|
||||
});
|
||||
|
||||
it('should search users by fullname', async function () {
|
||||
const uid = await User.create({ username: 'fullnamesearch2', fullname: 'Baris:Usakli' });
|
||||
const data = await socketUser.search({ uid: adminUid }, { query: 'baris:', searchBy: 'fullname' });
|
||||
assert(Array.isArray(data.users));
|
||||
assert.equal(data.users.length, 1);
|
||||
assert.equal(uid, data.users[0].uid);
|
||||
});
|
||||
|
||||
it('should return empty array if query is empty', function (done) {
|
||||
socketUser.search({ uid: testUid }, { query: '' }, function (err, data) {
|
||||
assert.ifError(err);
|
||||
|
||||
Reference in New Issue
Block a user