用猫鼬查询获取平均值

时间:2020-07-13 08:51:29

标签: node.js mongodb mongoose

我正在获取“地点”列表,其中猫鼬按位置和其他内容过滤,下面的代码可以正常工作。 但是我希望“ rate”的值是所有评论的平均值(而不是评论列表)的平均值。这是另一个集合的集合。

这就是我得到的:

{
"_id":"5f0ade7d1f84460434524d3d",
"name":"Fly",
...
"rate":[
    {"_id":"5f0bfca64ca1cc02ffe48faf","spot_id":"5f0ade7d1f84460434524d3d","rate":3}, 
    {"_id":"5f0bfdb44ca1cc02ffe48fb0","spot_id":"5f0ade7d1f84460434524d3d","rate":2}, 
    {"_id":"5f0bfdb44ca1cc02ffe48fb1","spot_id":"5f0ade7d1f84460434524d3d","rate":1}
  ]
},

但是我想要这样的结果:

{
   "_id":"5f0ade7d1f84460434524d3d",
   "name":"Fly",
   ...
   "rate": 2
},

我尝试了许多不同的方法,但我想我需要使用$ group,但无法弄清楚如何获得正确的输出。

评论架构:

const reviewsSchema = new mongoose.Schema({
    _id: {
        type: ObjectId,
        required: true,
    },
    spot_id: {
        type: ObjectId,
        required: true,
    },
    rate: {
        type: Number,
        required: true,
    },
})

现场模式

const spotsSchema = new mongoose.Schema({
    _id: {
        type: ObjectId,
        required: true,
    },
    name: {
        type: String,
        required: true,
    },
    ...
})

代码:

Spots.aggregate
  ([
    {
      $geoNear: {
          near: { type: "Point", coordinates: [ parseFloat(longitude), parseFloat(latitude) ] },
          distanceField: "location",
          maxDistance: parseInt(distance) * 1000,
          query: {
            $and: [
              { $or : filter },
              { $or : closed },
              { published: true }
            ]
          }
      }
    },
    { $match: {} },
    {
      $lookup:{
        from: 'reviews',
        localField: '_id',
        foreignField: 'spot_id',
        as: 'rate'
      }
    },
  ])

1 个答案:

答案 0 :(得分:1)

您真的很亲近,您只需要实际计算avg的值即可,可以使用$map$avg来完成,如下所示:

{
    $addFields: {
      rate: {
        $avg: {
          $map: {
            input: "$rate",
            as: "datum",
            in: "$$datum.rate"
          }
        }
      }
    }
  }

MongoPlayground