diff --git a/packages/hydrooj/src/model/setting.ts b/packages/hydrooj/src/model/setting.ts index 74d36eddb..2f32c50d7 100644 --- a/packages/hydrooj/src/model/setting.ts +++ b/packages/hydrooj/src/model/setting.ts @@ -287,7 +287,7 @@ DomainUserSetting(Schema.object({ rpInfo: Schema.any().extra('family', 'setting_storage').disabled().hidden(), - ...Object.fromEntries(['nAccept', 'nSubmit', 'nLike', 'rp', 'rpdelta', 'rank', 'level', 'join'].map((i) => ([ + ...Object.fromEntries(['nAccept', 'nSubmit', 'nLiked', 'rp', 'rpdelta', 'rank', 'level', 'join'].map((i) => ([ i, Schema.number().default(0).extra('family', 'setting_storage').disabled().hidden(), ]))), diff --git a/packages/hydrooj/src/script/problemStat.ts b/packages/hydrooj/src/script/problemStat.ts index 26ad4559b..44c2fb533 100644 --- a/packages/hydrooj/src/script/problemStat.ts +++ b/packages/hydrooj/src/script/problemStat.ts @@ -7,6 +7,27 @@ import db from '../service/db'; const sumStatus = (status) => ({ $sum: { $cond: [{ $eq: ['$status', status] }, 1, 0] } }); export async function udoc(report) { + const userStats = new Map(); + + report({ message: 'Udoc nLiked' }); + const likedPipeline = [ + { + $match: { + docType: document.TYPE_PROBLEM_SOLUTION, + vote: { $gt: 0 }, + }, + }, + { + $group: { + _id: { domainId: '$domainId', uid: '$owner' }, + nLiked: { $sum: '$vote' }, + }, + }, + ]; + for await (const adoc of document.coll.aggregate(likedPipeline, { allowDiskUse: true })) { + userStats.set(`${adoc._id.domainId}/${adoc._id.uid}`, { nLiked: adoc.nLiked }); + } + report({ message: 'Udoc' }); const pipeline = [ { @@ -31,20 +52,26 @@ export async function udoc(report) { }, }, ]; + for await (const adoc of db.collection('record').aggregate(pipeline, { allowDiskUse: true })) { + const key = `${adoc._id.domainId}/${adoc._id.uid}`; + const stat = userStats.get(key) || {}; + stat.nSubmit = adoc.nSubmit; + stat.nAccept = adoc.nAccept; + userStats.set(key, stat); + } + let bulk = db.collection('domain.user').initializeUnorderedBulkOp(); - const cursor = db.collection('record').aggregate(pipeline, { allowDiskUse: true }); - for await (const adoc of cursor) { - bulk.find({ - domainId: adoc._id.domainId, - uid: adoc._id.uid, - }).updateOne({ + for (const [key, stat] of userStats) { + const [domainId, uid] = key.split('/'); + bulk.find({ domainId, uid: +uid }).updateOne({ $set: { - nSubmit: adoc.nSubmit, - nAccept: adoc.nAccept, + nSubmit: stat.nSubmit || 0, + nAccept: stat.nAccept || 0, + nLiked: stat.nLiked || 0, }, }); if (bulk.batches.length > 100) { - await bulk.execute(); + await bulk.execute(); // eslint-disable-line no-await-in-loop bulk = db.collection('domain.user').initializeUnorderedBulkOp(); } } diff --git a/packages/ui-default/templates/user_detail.html b/packages/ui-default/templates/user_detail.html index 371329fc9..c1b87429a 100644 --- a/packages/ui-default/templates/user_detail.html +++ b/packages/ui-default/templates/user_detail.html @@ -153,7 +153,7 @@
-
{{ udoc.nLike or 0 }}
+
{{ udoc.nLiked or 0 }}
{{ _('Solutions Liked') }}