无法使用$ project获得特定的数据库值

时间:2019-01-26 07:55:03

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我试图在使用聚合和项目后获得标题,但是由于某种原因它没有在我的结果中显示它。我曾问过另一个有关如何对一组文档进行排序的问题,看来我必须使用聚合才能完成我认为微不足道的练习。我错了!无论如何...我已经注释了代码以解释我要做什么。

Product.aggregate([
  {
    $match: {
      // get the passed in ID which is a string and needs to be converted to ObjectId format (is there a better way to do this?)
      _id: new mongoose.Types.ObjectId(productId)
    }
  },
  {
    // deconstruct the array of objects
    $unwind: "$requests"
  },
  {
    // sort in required order of display
    $sort: {
      "requests.requestDt": -1
    }
  },
  {
    // group by the product ID and push into new array
    $group: {
      "_id": productId,
      "requests": {
        $push: "$requests"
      }
    }
  },
  {
   // project the data I want to display in my view
    $project: {
      "_id": 1,
      "title": 1,
      "requests": 1,
    }
  }
])

当我在控制台上进行日志记录时,会得到如下输出:

[{
    "_id": "5c4aaa22d0f10e038999afca",
    "requests": [{
            "_id": "5c4b2925d47f6e0a79378010",
            "userId": "5c25cddc73d10c02a75b3d55",
            "firstName": "test",
            "requestDt": "2019-01-25T15:20:05.410Z"
        },
        {
            "_id": "5c4b28e8d47f6e0a7937800f",
            "userId": "5c375260a6f58308e510711a",
            "firstName": "Joe",
            "requestDt": "2019-01-25T15:19:04.258Z"
        }
    ]
}]

因此,我从项目中的_id获取产品ID,以及请求,但没有标题,我不知道为什么?

以下是架构:

const productSchema = new Schema({
    title: {
        type: String,
        required: true,
    },
    category: {
        type: String,
        required: true
    },
    images: [
        {
            name: {
                type: String
            }
        }
    ],
    description: {
        type: String,
        required: true
    },
    userId: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    createdAt: {
        type: Date,
        default: Date.now
    },
    requests: [
        {
             userId: { type: Schema.Types.ObjectId, required: true},
             firstName: {type: String},
             requestDt: {type: Date, default: Date.now}
        }
    ]
});

更新:

我删除了$ group,现在可以访问它了。我的数据现在看起来像:

[{
        "_id": "5c4aaa22d0f10e038999afca",
        "title": "Some product",
        "requests": {
            "_id": "5c4b2925d47f6e0a79378010",
            "userId": "5c25cddc73d10c02a75b3d55",
            "firstName": "test",
            "requestDt": "2019-01-25T15:20:05.410Z"
        }
    },
    {
        "_id": "5c4aaa22d0f10e038999afca",
        "title": "Some product",
        "requests": {
            "_id": "5c4b28e8d47f6e0a7937800f",
            "userId": "5c375260a6f58308e510711a",
            "firstName": "Joe",
            "requestDt": "2019-01-25T15:19:04.258Z"
        }
    }
]

所以现在所有数据都包装在一个数组中,而不是请求中。但是我现在有重复的数据,即:产品标题显示两次,但我只需要一次。

要使用标题,请使用product[0].title,并将请求放入for循环中,例如:for (userRequest of product ),并访问数据,例如:serRequest.requests.motivation

这似乎是疯狂的漫长的路要走,只是按照“请求”进行排序,因此,如果有人有更好的解决方案,请发布。

1 个答案:

答案 0 :(得分:1)

您需要使用$first聚合来在$group阶段获得title

Product.aggregate([
  { "$match": { "_id": new mongoose.Types.ObjectId(productId) }},
  { "$unwind": "$requests" },
  { "$sort": { "requests.requestDt": -1 }},
  { "$group": {
    "_id": "$_id",
    "requests": { "$push": "$requests" },
    "title": { "$first": "$title" }
  }},
  { "$project": { "_id": 1, "title": 1, "requests": 1 }}
])