【问题标题】:Sorting and limiting array objects of a MongoDB document排序和限制 MongoDB 文档的数组对象
【发布时间】:2021-12-23 09:31:14
【问题描述】:

我正在处理我的第一个 MERN 全栈项目,但我遇到了后端分页、排序和过滤问题。

在项目(电子商务)中,我将“愿望清单”文档保存在数据库中。我想要实现的是:

  1. 限制保存在每页前端可见的愿望清单中的产品数量(例如:每页 4 个产品);
  2. 根据用户指定的产品名称过滤产品;
  3. 根据用户指定的顺序按日期对产品进行排序。

这是我的数据库文档示例:

{
  _id: 618c1a00b3867b1fac2649d8,
  user: 610d77436cbf3d3580539ffe,
  wishlistItems: [
    {
      _id: 611c20a4fc79341104b2393b,
      name: 'Matcha BIO - 40 gm',
      slug: 'Matcha-BIO-40-gm',
      date: '2021-11-10T19:14:08.769Z',
      price: 18.9,
      discount: null,
      image: [Object],
      createdAt: 2021-11-10T19:14:08.986Z,
      updatedAt: 2021-11-10T19:14:08.986Z
    }
  ],
  createdAt: 2021-11-10T19:14:08.986Z,
  updatedAt: 2021-11-10T19:14:08.986Z,
  __v: 0
}

“wishlistItems”是我要排序、过滤和限制的数组。

这是我在后端的愿望清单控制器:

export const getWishListUser = async (req, res) => {
  try {
    const searchTerm = req.query.name;
    let sort = !req.query.sort ? -1 : req.query.sort;
    const page = parseInt(req.query.page) || 1;
    const pageSize = parseInt(req.query.limit) || 4;
    const skip = (page - 1) * pageSize;

    let totalWishlist = await WishlistUser.findOne({ user: req.user._id });
    

    if (totalWishlist) {
      const total = totalWishlist.wishlistItems.length;

      const pages = Math.ceil(total / pageSize);

      let result = await WishlistUser.aggregate([
        {
          $match: {
            $and: [
              { user: req.user._id },
              { "wishlistItems.name": { $regex: searchTerm, $options: "i" } },
            ],
          },
        },
        { $unwind: "$whishlistItems" },
        { $sort: { "wishlistItems.date": sort } },
        { $limit: pageSize },
        { $skip: skip },
        {
          $group: { user: "$user", wishlistItems: { $push: "$wishlistItems" } },
        },
      ]);

      console.log(result);
      if (result) {
        return res
          .status(200)
          .json({ wishlistItems: result, count: totalWishlist, page, pages });
      } else {
        return res
          .status(404)
          .json({ errorMessage: "User wishlist not found" });
      }
    } else {
      return res.status(404).json({ errorMessage: "User wishlist not found" });
    }
  } catch (error) {
    return res.status(500).json({ errorMessage: `${error}` });
  }
};

这是前端调用:

 const getWishlistUser = async (name, sort, page) => {
  const response = await axios.get(
    `http://localhost:5020/api/user/wishlist/get-wishlist-user?name=${name}&sort=${sort}&page=${page}`,
    config2
  );
  return response;
};

 const gettingWishlistUser = (searchTerm, sort, page) => {
    setFavoriteProd({ ...favoriteProd, loading: true });
    getWishlistUser(searchTerm, sort, page)
      .then((response) => {
        setFavoriteProd({
          ...favoriteProd,
          wishlistItems: response.data.wishlistItems,
          count: response.data.count,
          loading: false,
        });
        setPages(response.data.pages);
      })
      .catch((error) => {
        setFavoriteProd({
          ...favoriteProd,
          errorMessage: error.toString(),
          loading: false,
        });
        setPages(1);
      });
  };

  useEffect(() => {
    if (isAuthenticated() && isAuthenticated().role === 0) {
      gettingWishlistUser(searchTerm, sort, page);
    }
  }, [page, sort, searchTerm, pages]);

我怎样才能达到这个结果? 非常感谢!

【问题讨论】:

    标签: node.js mongodb sorting pagination mern


    【解决方案1】:

    我认为你的主要问题是你在限制之后跳过。

    想一想:如果您首先限制 X 值,那么您将获得尽可能多的值(例如 10 个),然后您跳过 X 元素...您将从剩余的 10 个元素中跳过。您必须跳过所有元素并限制尽可能多的元素。

    使用此查询,您可以跳过和限制:

    db.collection.aggregate([
      {
        "$unwind": "$wishlistItems"
      },
      {
        "$sort": {
          "wishlistItems.date": 1
        }
      },
      {
        "$skip": 2
      },
      {
        "$limit": 2
      },
      {
        "$group": {
          "_id": "$_id",
          "user": {
            "$first": "$user"
          },
          "createdAt": {
            "$first": "$createdAt"
          },
          "updatedAt": {
            "$first": "$updatedAt"
          },
          "wishlistItems": {
            "$push": "$wishlistItems"
          }
        }
      }
    ])
    

    例如here

    另外,作为补充,在$skiphere之前有$limit的例子

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      相关资源
      最近更新 更多