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

improve createtaglistwithcount method

yuto-o 4 лет назад
Родитель
Сommit
d7e3d3d1a8

+ 2 - 2
packages/app/src/components/TagsList.jsx

@@ -40,11 +40,11 @@ class TagsList extends React.Component {
 
 
   async getTagList(selectPageNumber) {
   async getTagList(selectPageNumber) {
     const limit = this.state.pagingLimit;
     const limit = this.state.pagingLimit;
-    const offset = (selectPageNumber - 1) * limit;
+    const skip = (selectPageNumber - 1) * limit;
     let res;
     let res;
 
 
     try {
     try {
-      res = await apiGet('/tags.list', { limit, offset });
+      res = await apiGet('/tags.list', { limit, skip });
     }
     }
     catch (error) {
     catch (error) {
       toastError(error);
       toastError(error);

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

@@ -24,11 +24,13 @@ const schema = new mongoose.Schema({
     type: ObjectId,
     type: ObjectId,
     ref: 'Tag',
     ref: 'Tag',
     required: true,
     required: true,
+    index: true,
   },
   },
   isPageTrashed: {
   isPageTrashed: {
     type: Boolean,
     type: Boolean,
     default: false,
     default: false,
     required: true,
     required: true,
+    index: true,
   },
   },
 });
 });
 // define unique compound index
 // define unique compound index
@@ -44,22 +46,28 @@ schema.plugin(uniqueValidator);
 class PageTagRelation {
 class PageTagRelation {
 
 
   static async createTagListWithCount(option) {
   static async createTagListWithCount(option) {
-    const Tag = mongoose.model('Tag');
     const opt = option || {};
     const opt = option || {};
     const sortOpt = opt.sortOpt || {};
     const sortOpt = opt.sortOpt || {};
-    const offset = opt.offset || 0;
-    const limit = opt.limit || 50;
+    const skip = opt.skip;
+    const limit = opt.limit;
 
 
-    const existTagIds = await Tag.find().distinct('_id');
     const tags = await this.aggregate()
     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(skip)
+      .limit(limit);
+
+    const totalCount = (await this.find({ isPageTrashed: false }).distinct('relatedTag')).length;
+
+    return { data: tags, totalCount };
   }
   }
 
 
   static async findByPageId(pageId) {
   static async findByPageId(pageId) {

+ 6 - 24
packages/app/src/server/routes/tag.js

@@ -210,37 +210,19 @@ module.exports = function(crowi, app) {
    * @apiGroup Tag
    * @apiGroup Tag
    *
    *
    * @apiParam {Number} limit
    * @apiParam {Number} limit
-   * @apiParam {Number} offset
+   * @apiParam {Number} skip
    */
    */
   api.list = async function(req, res) {
   api.list = async function(req, res) {
     const limit = +req.query.limit || 50;
     const limit = +req.query.limit || 50;
-    const offset = +req.query.offset || 0;
+    const skip = +req.query.skip || 0;
     const sortOpt = { count: -1, _id: -1 };
     const sortOpt = { count: -1, _id: -1 };
-    const queryOptions = { offset, limit, sortOpt };
-    const result = {};
+    const queryOptions = { skip, limit, sortOpt };
 
 
     try {
     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) {
     catch (err) {
       return res.json(ApiResponse.error(err));
       return res.json(ApiResponse.error(err));