core: discussion: sort by creation time

pull/490/head
undefined 2 years ago
parent 00ac1c957a
commit 0cbb51cc19

@ -1,5 +1,4 @@
import { omit } from 'lodash'; import { omit } from 'lodash';
import moment from 'moment-timezone';
import { FilterQuery, ObjectID } from 'mongodb'; import { FilterQuery, ObjectID } from 'mongodb';
import { Context } from '../context'; import { Context } from '../context';
import { DiscussionNodeNotFoundError, DocumentNotFoundError } from '../error'; import { DiscussionNodeNotFoundError, DocumentNotFoundError } from '../error';
@ -13,7 +12,6 @@ import { buildProjection } from '../utils';
import * as contest from './contest'; import * as contest from './contest';
import * as document from './document'; import * as document from './document';
import problem from './problem'; import problem from './problem';
import ScheduleModel from './schedule';
import * as training from './training'; import * as training from './training';
export interface DiscussionDoc extends Document { } export interface DiscussionDoc extends Document { }
@ -119,7 +117,7 @@ export function count(domainId: string, query: FilterQuery<DiscussionDoc>) {
export function getMulti(domainId: string, query: FilterQuery<DiscussionDoc> = {}, projection = PROJECTION_LIST) { export function getMulti(domainId: string, query: FilterQuery<DiscussionDoc> = {}, projection = PROJECTION_LIST) {
return document.getMulti(domainId, document.TYPE_DISCUSSION, query) return document.getMulti(domainId, document.TYPE_DISCUSSION, query)
.sort({ pin: -1, sort: -1 }) .sort({ pin: -1, docId: -1 })
.project(buildProjection(projection)); .project(buildProjection(projection));
} }
@ -314,7 +312,8 @@ export async function getListVnodes(domainId: string, ddocs: any, getHidden = fa
return res; return res;
} }
bus.on('problem/delete', async (domainId, docId) => { export function apply(ctx: Context) {
ctx.on('problem/delete', async (domainId, docId) => {
const dids = await document.getMulti( const dids = await document.getMulti(
domainId, document.TYPE_DISCUSSION, domainId, document.TYPE_DISCUSSION,
{ parentType: document.TYPE_PROBLEM, parentId: docId }, { parentType: document.TYPE_PROBLEM, parentId: docId },
@ -329,36 +328,6 @@ bus.on('problem/delete', async (domainId, docId) => {
document.deleteMulti(domainId, document.TYPE_DISCUSSION_REPLY, { docId: { $in: drids } }), document.deleteMulti(domainId, document.TYPE_DISCUSSION_REPLY, { docId: { $in: drids } }),
]); ]);
}); });
const t = Math.exp(-0.15);
async function updateSort() {
const cursor = document.coll.find({ docType: document.TYPE_DISCUSSION });
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
const data = await cursor.next();
if (!data) return;
// eslint-disable-next-line no-await-in-loop
const rCount = await getMultiReply(data.domainId, data.docId).count();
const sort = ((data.sort || 100) + Math.max(rCount - (data.lastRCount || 0), 0) * 10) * t;
// eslint-disable-next-line no-await-in-loop
await document.coll.updateOne({ _id: data._id }, { $set: { sort, lastRCount: rCount } });
}
}
export function apply(ctx: Context) {
ctx.using(['worker'], async ({ worker }) => {
worker.addHandler('discussion.sort', updateSort);
if (!await ScheduleModel.count({ type: 'schedule', subType: 'discussion.sort' })) {
await ScheduleModel.add({
type: 'schedule',
subType: 'discussion.sort',
executeAfter: moment().minute(0).second(0).millisecond(0).toDate(),
interval: [1, 'hour'],
});
}
});
} }
global.Hydro.model.discussion = { global.Hydro.model.discussion = {

@ -433,8 +433,8 @@ export async function apply(ctx: Context) {
// For problem solution // For problem solution
{ key: { domainId: 1, docType: 1, parentType: 1, parentId: 1, vote: -1, docId: -1 }, name: 'solution', sparse: true }, { key: { domainId: 1, docType: 1, parentType: 1, parentId: 1, vote: -1, docId: -1 }, name: 'solution', sparse: true },
// For discussion // For discussion
{ key: { domainId: 1, docType: 1, pin: -1, sort: -1, docId: -1 }, name: 'discussionSort', sparse: true }, { key: { domainId: 1, docType: 1, pin: -1, docId: -1 }, name: 'discussionSort', sparse: true },
{ key: { domainId: 1, docType: 1, parentType: 1, parentId: 1, pin: -1, sort: -1, docId: -1 }, name: 'discussionNodeSort', sparse: true }, { key: { domainId: 1, docType: 1, parentType: 1, parentId: 1, pin: -1, docId: -1 }, name: 'discussionNodeSort', sparse: true },
// Hidden doc // Hidden doc
{ key: { domainId: 1, docType: 1, hidden: 1, docId: -1 }, name: 'hiddenDoc', sparse: true }, { key: { domainId: 1, docType: 1, hidden: 1, docId: -1 }, name: 'hiddenDoc', sparse: true },
// For contest // For contest

@ -560,6 +560,11 @@ const scripts: UpgradeScript[] = [
await db.collection('oplog').updateMany({}, { $unset: { 'args.verifyPassword': '' } }); await db.collection('oplog').updateMany({}, { $unset: { 'args.verifyPassword': '' } });
return true; return true;
}, },
async function _73_74() {
await db.collection('document').updateMany({ docType: document.TYPE_DISCUSSION }, { $unset: { sort: '' } });
await ScheduleModel.deleteMany({ subType: 'discussion.sort' });
return true;
},
]; ];
export default scripts; export default scripts;

Loading…
Cancel
Save