Mongodb Moongoose聚合$match与id';s
我想通过ID(Mongodb Moongoose聚合$match与id';s,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我想通过ID(56e641d4864e5b780bb992c6和56e65504a323ee0812e511f2)显示产品,并在扣除折扣后显示价格(如果可用) 我可以使用aggregate计算最终价格,但这将返回集合中的所有文档,如何使其仅返回匹配的ID "_id" : ObjectId("56e641d4864e5b780bb992c6"), "title" : "Keyboard", "discount" : NumberInt(10), "price" : NumberInt(1000
56e641d4864e5b780bb992c6
和56e65504a323ee0812e511f2
)显示产品,并在扣除折扣后显示价格(如果可用)
我可以使用aggregate计算最终价格,但这将返回集合中的所有文档,如何使其仅返回匹配的ID
"_id" : ObjectId("56e641d4864e5b780bb992c6"),
"title" : "Keyboard",
"discount" : NumberInt(10),
"price" : NumberInt(1000)
"_id" : ObjectId("56e65504a323ee0812e511f2"),
"title" : "Mouse",
"discount" : NumberInt(0),
"price" : NumberInt(1000)
"_id" : ObjectId("56d90714a48d2eb40cc601a5"),
"title" : "Speaker",
"discount" : NumberInt(10),
"price" : NumberInt(1000)
这是我的问题
productModel.aggregate([
{
$project: {
title : 1,
price: {
$cond: {
if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price"
}
}
}
}
], function(err, docs){
if (err){
console.log(err)
}else{
console.log(docs)
}
})
如果我在查询中添加这个$,它将返回空数组
productModel.aggregate([
{
$match: {_id: {$in: ids}}
},
{
$project: {
title : 1,
price: {
$cond: {
if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price"
}
}
}
}
], function(err, docs){
if (err){
console.log(err)
}else{
console.log(docs)
}
})
您的id
变量将由“字符串”构成,而不是ObjectId
值
在常规查询中,Mongoose将ObjectId
的“autocast”字符串值转换为正确的类型,但这与第1399期中的描述相同
相反,您必须执行正确的强制转换才能手动键入:
ids=ids.map(函数(el){return mongoose.Types.ObjectId(el)})
然后,您可以在管道阶段使用它们:
{“$match”:{“\u id”:{“$in”:ids}}
原因是聚合管道“通常”会改变文档结构,因此mongoose不会假定“模式”适用于任何给定管道阶段的文档
“第一”管道阶段(当它是$match
阶段时)应该这样做,这是有争议的,因为文档确实没有更改。但目前情况并非如此
任何可能是“字符串”或至少不是正确BSON类型的值都需要手动强制转换才能匹配。您的ids
变量将由“字符串”而不是ObjectId
值构成
在常规查询中,Mongoose将ObjectId
的“autocast”字符串值转换为正确的类型,但这与第1399期中的描述相同
相反,您必须执行正确的强制转换才能手动键入:
ids=ids.map(函数(el){return mongoose.Types.ObjectId(el)})
然后,您可以在管道阶段使用它们:
{“$match”:{“\u id”:{“$in”:ids}}
原因是聚合管道“通常”会改变文档结构,因此mongoose不会假定“模式”适用于任何给定管道阶段的文档
“第一”管道阶段(当它是$match
阶段时)应该这样做,这是有争议的,因为文档确实没有更改。但目前情况并非如此
任何可能是“字符串”或至少不是正确BSON类型的值都需要手动强制转换才能匹配。您只需将id转换为
let id = mongoose.Types.ObjectId(req.query.id);
然后比赛
{ $match: { _id: id } },
您只需将您的id转换为
let id = mongoose.Types.ObjectId(req.query.id);
然后比赛
{ $match: { _id: id } },
在mongoose中,它可以与find配合使用({u id:'606c1ceb362b366a841171dc'})
但是在使用聚合函数时,我们必须使用mongoose对象将_id转换为object,例如
$match:{“\u id”:mongoose.Types.ObjectId(“606c1ceb362b366a841171dc”)}
这很好用
在mongoose中,它可以与find配合使用({u id:'606c1ceb362b366a841171dc'})
但是在使用聚合函数时,我们必须使用mongoose对象将_id转换为object,例如
$match:{“\u id”:mongoose.Types.ObjectId(“606c1ceb362b366a841171dc”)}
这很好。就是这样,现在可以了。但通常我在findOneAndUpdate或其他查询中将id作为字符串抛出,效果很好,问题只会在聚合中发生吗?@MuhammadFasalirRahman这正是我的回答。.find()
可以使用模式
,对于\u id
字段,该模式的默认类型当然是ObjectId
。聚合管道不使用模式
,实际上我已经解释过了;唉。。我在我的模式静态方法中创建了一个lamdaconst castUserId=(userId)=>mongoose.Types.ObjectId(userId)
现在我很高兴……在这个问题上浪费了几个小时……感谢您的解决方案,它现在可以工作了。但通常我在findOneAndUpdate或其他查询中将id作为字符串抛出,效果很好,问题只会在聚合中发生吗?@MuhammadFasalirRahman这正是我的回答。.find()
可以使用模式
,对于\u id
字段,该模式的默认类型当然是ObjectId
。聚合管道不使用模式
,实际上我已经解释过了;唉。。我在我的模式静态方法中创建了一个lamdaconst castUserId=(userId)=>mongoose.Types.ObjectId(userId)