猫鼬中可选存在的字段的猫鼬聚合 - 评级计算

时间:2021-06-10 17:02:27

标签: node.js mongodb mongoose aggregation

我的产品文档是这样的:

{
  "_id": {
    "$oid": "60999af1160b0eebed51f203"
  },
  "name": "Olive Skin care On1",
  "business": {
    "$oid": "609fa1d25adc157a33c59098"
  },
    "ratings": [{
    "_id": {
      "$oid": "60bdb541d6212ec44e62273c"
    },
    "user": {
      "$oid": "5fdce4bd75dbe4864fcd5001"
    },
    "rating": 5
  }]
}

我有这个 mongoose 查询来获取产品详细信息以及产品评级。一些产品有评级字段,而另一些则没有。当我按此处所示进行查询时,它会按预期返回响应并计算出平均评分。响应如下:

[
  {
      "_id": "609a657f2bf43c290fb22df8",
      "name": "Olive babay Oil",
      "business": "6079ed084d9ab0c3171317ea",
      "averageRating": 5
  }
]

这是查询:

const productArray = await Product.aggregate([
    {
        $match: {
            _id: mongooseProductId,
        },
    },
    { $unwind: "$ratings" },
    {
        $project: {
            averageRating: { $avg: "$ratings.rating" },
            name: 1,
            business: 1,
        },
    },
]);

但是,如果通过删除 ratings 字段修改了上面的相同产品,则下面的查询将返回一个空数组。 如何编写查询以确保 ratings 字段是否存在,如果满足匹配条件,我不会得到空数组。

这意味着当我的产品文档中不存在 ratings 字段时,我可以获得这样的预期响应:

[
  {
      "_id": "609a657f2bf43c290fb22df8",
      "name": "Olive babay Oil",
      "business": "6079ed084d9ab0c3171317ea",
      "averageRating": null
  }
]

当评级字段存在时:

[
  {
      "_id": "609a657f2bf43c290fb22df8",
      "name": "Olive babay Oil",
      "business": "6079ed084d9ab0c3171317ea",
      "averageRating": 5
  }
]

1 个答案:

答案 0 :(得分:0)

基于@turivishal 的评论。下面的查询解决了这个问题。

const productArray = await Product.aggregate([
    {
        $match: {
            _id: mongooseProductId,
        },
    },
    { $unwind:{ path: "$ratings", preserveNullAndEmptyArrays: true } },
    {
        $project: {
            averageRating: { $avg: "$ratings.rating" },
            name: 1,
            business: 1,
        },
    },
]);