猫鼬中的聚合搜索分页

问题描述 投票:0回答:2
const page = 1;
const limit = 10;

const searchResultsArray = await mongoose.connection.db
                .collection('game_activity')
                .aggregate([
                    {
                        $match: {
                            game_id
                        }
                    },
                    {
                        $addFields: {
                            activities: {
                                $filter: {
                                    input: '$activity',
                                    as: 'activity',
                                    cond: {
                                        $and: condition
                                    }
                                }
                            }
                        }
                    },
                    {
                        $project: {
                            activities: 1,
                            activity_number: { <--- can't read property error
                                $size: '$activities'
                            }
                        }
                    },
                    { $limit: 50 },
                    {
                        $facet: {
                            paginatedResult: [ { $sort: searchFilter }, { $skip: (page - 1) * limit } ]
                        }
                    }
                ])
                .toArray();
            const searchResultsObject = searchResultsArray[0];
            if (
                searchResultsObject.paginatedResult[0].activity_number === undefined ||
                searchResultsObject.paginatedResult[0].activity_number == 0
            ) {
                const result = {
                    no_activities: true
                };
                res.json(result);
            } else {
                const result = {
                    search_result: {
                        total_activities: searchResultsObject.paginatedResult[0].activity_number,
                        current_page: page,
                        last_page: Math.ceil(searchResultsObject.paginatedResult[0].activity_number / 10),
                        searched_activities: searchResultsObject.paginatedResult[0].activities
                    },
                    no_activities: false
                };
                res.json(result);
            }

我有这个

.aggregate()
搜索功能并尝试应用分页结果。这种格式适用于其他搜索,但在这个
aggregate()
搜索中,我有 2 个问题。

console.log(searchResultsObject.paginatedResult[0]); 
-------- result --------
{
  search_result: {
    total_activities: 16,
    current_page: 1,
    last_page: 2,
    searched_activities: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object]
    ]
  },
  no_activities: false
}
  1. const limit = 10
    不适用于此处。它返回所有
    activities

  2. 当我设置

    const page = 2;
    时,我收到
    TypeError: Cannot read property 'activity_number' of undefined
    这个错误并且
     console.log(searchResultsObject.paginatedResult[0]);
    显示“未定义

我想每页返回 10 个游戏活动,所以在这种情况下,如果我设置

const page =2;
,那么它将返回其余 6 个
activities
。我不太清楚如何解决这个问题,因为这适用于我的其他
.aggregate()
搜索。

------------ MongoDB 文档---------

{
    "_id": {
        "$oid": "601942d93aca6ee8cb300327"
    },
    "location_id": "ddff23323443",
    "activity": [{
        "activity_id": "VVINxmhRHsnMwvfT",
        "created_by": {
            "id": "aa332",
           
        },
        "activity_type": "league_of_legends",
        "activity_info": {
            "location_id": "ddff23323443",
            "activity_time": "2021-02-02 05:45:00.000Z",
            "game_code": "6"
        },
        "attendee": ["aa332"]
    }, {
        "activity_id": "EBZNKmsFKDgdeDz0",
        "created_by": {
            "id": "aa332",
           
        },
        "activity_type": "league_of_legends",
        "activity_info": {
            "id": "ddff23323443",
            "activity_time": "2021-02-02 05:45:00.000Z",
            "game_code": "6"
        },
        "attendee": ["aa332"]
    }, {
        "activity_id": "j8J1Jlk8MtWPi1HT",
        "created_by": {
            "id": "aa332",
           
        },
        "activity_type": "league_of_legends",
        "activity_info": {
            "location_id": "bvvsd33",
            "activity_time": "2021-02-02 05:45:00.000Z",
            "game_code": "6"
        },
        "attendee": ["aa332"]
    }]
}

-----期待-----

const page = 1
 {
      search_result: {
        total_activities: 16,
        current_page: 1,
        last_page: 2,
        searched_activities: [
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
        ]
      },
      no_activities: false
    }

const page = 2
 {
      search_result: {
        total_activities: 16,
        current_page: 2,
        last_page: 2,
        searched_activities: [
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
        ]
      },
      no_activities: false
    }
node.js mongoose
2个回答
2
投票

根据您的尝试,您的期望并不明确,我可以解释基本的分页过程,

  • 分页配置
const page = 1;
const limit = 10;
// If you are starting page number from 1 then you need to minus 1
const skip = (page - 1) * limit;
  • $unwind
    解构
    activities
    数组
  • $replaceRoot
    activities
    对象替换为根
  • $sort
    文档
  • $facet
    用于分隔结果、结果数据和计数,
    $skip
    应位于
    $limit
  • 之前
const searchResultsArray = await mongoose.connection.db.collection('game_activity').aggregate([
  { $match: { _id: game_id } },
  {
    $project: {
      activities: {
        $filter: {
          input: '$activity',
          as: 'activity',
          cond: { $and: condition }
        }
      }
    }
  },
  { $unwind: "$activities" },
  { $replaceRoot: { newRoot: "$activities" } },
  { $sort: searchFilter },
  {
    $facet: {
      searched_activities: [
        { $skip: skip },
        { $limit: limit }
      ],
      total_activities: [
        { $count: "count" }
      ]
    }
  }
]).toArray();
  • 无数据验证响应
// No Data Fond!
if (!searchResultsArray[0].total.length) {
  res.json({ no_activities: true });
  return;
}
  • 成功响应
res.json({
  search_result: {
    total_activities: searchResultsArray[0].total_activities[0].count,
    current_page: page,
    last_page: Math.ceil(searchResultsArray[0].total_activities[0].count / limit),
    searched_activities: searchResultsArray[0].searched_activities
  },
  no_activities: false
});

将上面的代码按顺序组合在一起尝试。


0
投票

非常好的答案,谢谢。如果我不使用磁盘写入,那么是否有其他方法可以在 Mongo 中进行分页,因为 Facet 的大小限制为 16MB?

© www.soinside.com 2019 - 2024. All rights reserved.