You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询:如何对对象数组类型的结果进行切片?解决$slice参数类型错误问题

解决MongoDB聚合中$slice的类型错误问题

首先得说清楚你为啥踩这个坑:你用$slice的思路完全错了。$slice是专门用来处理数组字段的,但你在page_limit_stage里把$$CURRENT(或者后来改成的$CURRENT)传给它——这玩意儿是管道里的单个文档对象,不是数组,MongoDB自然会报错说“First argument to $slice must be an array, but is of type: object”。

你的需求是对聚合结果做分页,对吧?那根本不需要用$slice,MongoDB聚合自带$skip和$limit阶段干这个,这俩是作用在整个文档流上的,专门用来实现分页逻辑。

正确的修改方案

删掉你原来的page_limit_stage,换成$skip和$limit两个阶段,放到管道的最后就行:

const filterProfiles = async function filterProfiles() {
  const { users_filter_option, profiles_filter_option } = prepareProfilesFilterSearchOptions();
  const profile_stage = {
    $lookup: {
      from: "profiles",
      let: { profile_id: "$profile" },
      pipeline: [profiles_filter_option],
      as: "profile",
    },
  };
  const profile_populate_options = [
    {
      $lookup: {
        from: "schema_name_1",
        localField: "profile.schema_name_1",
        foreignField: "_id",
        as: "schema_name_1",
      },
    },
    {
      $lookup: {
        from: "schema_name_2",
        localField: "profile.schema_name_2",
        foreignField: "_id",
        as: "schema_name_2",
      },
    },
  ];
  const project_stage = {
    $project: {
      user_id: "$_id",
      name: "$name",
      surname: "$surname",
      country: "$country",
      schema_name_2: { $arrayElemAt: ["$schema_name_2", 0] },
      schema_name_1: "$schema_name_1",
    },
  };
  let limit = 5;
  let skip = limit * 1; // 这里对应第2页,第1页的话skip应该设为0
  // 替换原page_limit_stage为$skip和$limit阶段
  const pipeline = [
    users_filter_option,
    profile_stage,
    ...profile_populate_options,
    { $unwind: "$profile" },
    project_stage,
    { $skip: skip }, // 跳过指定数量的前置文档
    { $limit: limit } // 限制返回的文档数量
  ];
  const users = await User.aggregate(pipeline);
  return users;
};

为啥原来的方法行不通?

再给你理清楚逻辑:

  • $project阶段是针对单个文档做字段投影的,它处理的是单个对象,不是整个结果数组。
  • $slice的正确用法是处理文档内的数组字段,比如你有一个tags数组,想取前3个元素,写法是tags: { $slice: ["$tags", 3] },这才是合规的。
  • 而对整个聚合结果做分页,必须用$skip+$limit:$skip先跳过指定数量的文档,$limit再限制返回条数,这是MongoDB聚合实现分页的标准方式。

这样修改后,你就能得到正确的分页结果,再也不会碰到那个类型错误了。

内容的提问来源于stack exchange,提问作者AG_HIHI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:44:48