Просмотр исходного кода

Merge pull request #4722 from weseek/imprv/79427-81596-improve-performance-about-tag-page

Imprv: improve performance about tag page
yuto-o 4 лет назад
Родитель
Сommit
16c64a3ede

+ 20 - 12
packages/app/src/server/models/page-tag-relation.js

@@ -24,11 +24,13 @@ const schema = new mongoose.Schema({
     type: ObjectId,
     ref: 'Tag',
     required: true,
+    index: true,
   },
   isPageTrashed: {
     type: Boolean,
     default: false,
     required: true,
+    index: true,
   },
 });
 // define unique compound index
@@ -44,22 +46,28 @@ schema.plugin(uniqueValidator);
 class PageTagRelation {
 
   static async createTagListWithCount(option) {
-    const Tag = mongoose.model('Tag');
     const opt = option || {};
     const sortOpt = opt.sortOpt || {};
-    const offset = opt.offset || 0;
-    const limit = opt.limit || 50;
+    const offset = opt.offset;
+    const limit = opt.limit;
 
-    const existTagIds = await Tag.find().distinct('_id');
     const tags = await this.aggregate()
-      .match({ relatedTag: { $in: existTagIds }, isPageTrashed: false })
-      .group({ _id: '$relatedTag', count: { $sum: 1 } })
-      .sort(sortOpt);
-
-    const list = tags.slice(offset, offset + limit);
-    const totalCount = tags.length;
-
-    return { list, totalCount };
+      .match({ isPageTrashed: false })
+      .lookup({
+        from: 'tags',
+        localField: 'relatedTag',
+        foreignField: '_id',
+        as: 'tag',
+      })
+      .unwind('$tag')
+      .group({ _id: '$relatedTag', count: { $sum: 1 }, name: { $first: '$tag.name' } })
+      .sort(sortOpt)
+      .skip(offset)
+      .limit(limit);
+
+    const totalCount = (await this.find({ isPageTrashed: false }).distinct('relatedTag')).length;
+
+    return { data: tags, totalCount };
   }
 
   static async findByPageId(pageId) {

+ 3 - 21
packages/app/src/server/routes/tag.js

@@ -217,30 +217,12 @@ module.exports = function(crowi, app) {
     const offset = +req.query.offset || 0;
     const sortOpt = { count: -1, _id: -1 };
     const queryOptions = { offset, limit, sortOpt };
-    const result = {};
 
     try {
-      // get tag list contains id and count properties
-      const listData = await PageTagRelation.createTagListWithCount(queryOptions);
-      const ids = listData.list.map((obj) => { return obj._id });
-
-      // get tag documents for add name data to the list
-      const tags = await Tag.find({ _id: { $in: ids } });
-
-      // add name property
-      result.data = listData.list.map((elm) => {
-        const data = {};
-        const tag = tags.find((tag) => { return (tag.id === elm._id.toString()) });
-
-        data._id = elm._id;
-        data.name = tag.name;
-        data.count = elm.count; // the number of related pages
-        return data;
-      });
-
-      result.totalCount = listData.totalCount;
+      // get tag list contains id name and count properties
+      const tagsWithCount = await PageTagRelation.createTagListWithCount(queryOptions);
 
-      return res.json(ApiResponse.success(result));
+      return res.json(ApiResponse.success(tagsWithCount));
     }
     catch (err) {
       return res.json(ApiResponse.error(err));