Mongoose 聚合查询的坑及解决方案

阅读时长 5 分钟读完

Mongoose 是一个在 Node.js 环境下操作 MongoDB 数据库的 ORM 框架,提供了丰富的查询 API。其中聚合查询可以对数据进行分组、统计、筛选等操作,是一个非常强大的功能。但在使用过程中,我们也可能会遇到一些坑,本文将介绍这些坑并提供解决方案。

坑一:$lookup 时不加 as 字段

在进行聚合查询时,我们经常需要进行关联查询,此时可以使用 $lookup 操作符。但如果在 $lookup 中没有指定 as 字段,会导致后续操作无法正确执行。

例如,我们有两个集合 orderscustomers,需要查询每个订单所属的客户信息,可以使用以下代码:

-- -------------------- ---- -------
-----------------
  -
    -------- -
      ----- ------------
      ----------- -------------
      ------------- -----
    -
  -
--
展开代码

这段代码会返回一个包含 orderscustomers 字段的对象数组,但是我们无法通过 orders.customerId 获取到正确的客户信息。原因是没有指定 as 字段,导致 customers 字段被覆盖了。

解决方案是在 $lookup 中指定 as 字段,例如:

-- -------------------- ---- -------
-----------------
  -
    -------- -
      ----- ------------
      ----------- -------------
      ------------- ------
      --- ----------
    -
  -
--
展开代码

这样就可以通过 orders.customer 获取到正确的客户信息了。

坑二:$project 中不支持使用 $sum 等操作符

在聚合查询中,我们经常需要对数据进行统计,例如求和、平均值等。可以使用 $sum$avg 等操作符来实现。但是在 $project 中使用这些操作符会导致查询失败。

例如,我们需要查询每个客户的订单数量和订单总金额,可以使用以下代码:

-- -------------------- ---- -------
--------------------
  -
    -------- -
      ----- ---------
      ----------- ------
      ------------- -------------
      --- --------
    -
  --
  -
    --------- -
      ----- --
      ----------- - ----- ---------------- --
      ------------ - ----- ---------------- -
    -
  -
--
展开代码

这段代码会返回一个包含客户姓名、订单数量和订单总金额的对象数组,但是订单数量和订单总金额都是 NaN。原因是 $sum 操作符只能用在 $group 中,不能用在 $project 中。

解决方案是在 $group 中进行统计,例如:

-- -------------------- ---- -------
--------------------
  -
    -------- -
      ----- ---------
      ----------- ------
      ------------- -------------
      --- --------
    -
  --
  -
    ------- -
      ---- -------
      ----- - ------- ------- --
      ----------- - ----- - ------ --------- - --
      ------------ - ----- ---------------- -
    -
  --
  -
    --------- -
      ----- --
      ----------- --
      ------------ -
    -
  -
--
展开代码

这样就可以正确地查询出每个客户的订单数量和订单总金额了。

坑三:$group 中使用 $push 时会出现重复数据

在进行聚合查询时,我们经常需要对数据进行分组,可以使用 $group 操作符。在 $group 中使用 $push 操作符可以将数据放到数组中,但是会出现重复数据的问题。

例如,我们需要查询每个客户的订单信息,可以使用以下代码:

-- -------------------- ---- -------
--------------------
  -
    -------- -
      ----- ---------
      ----------- ------
      ------------- -------------
      --- --------
    -
  --
  -
    ------- -
      ---- -------
      ----- - ------- ------- --
      ------- - ------ --------- -
    -
  -
--
展开代码

这段代码会返回一个包含客户姓名和订单信息的对象数组,但是订单信息中会出现重复数据。原因是 $push 操作符会将符合条件的数据全部放入数组中,而不是按照客户进行分组。

解决方案是使用 $addToSet 操作符,它会将符合条件的数据放入数组中,并去重。例如:

-- -------------------- ---- -------
--------------------
  -
    -------- -
      ----- ---------
      ----------- ------
      ------------- -------------
      --- --------
    -
  --
  -
    ------- -
      ---- -------
      ----- - ------- ------- --
      ------- - ---------- --------- -
    -
  -
--
展开代码

这样就可以正确地查询出每个客户的订单信息了。

结语

本文介绍了 Mongoose 聚合查询中的三个坑,并提供了相应的解决方案。希望能对大家学习和使用 Mongoose 有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d56225a941bf7134a026bf

纠错
反馈

纠错反馈