问题描述
我想按ID(56e641d4864e5b780bb992c6
和56e65504a323ee0812e511f2
)显示产品,并在扣除折扣后显示价格(如果有).
I want to show products by ids (56e641d4864e5b780bb992c6
and 56e65504a323ee0812e511f2
) and show price after subtracted by discount if available.
我可以使用合计来计算最终价格,但这会返回集合中的所有文档,如何使其仅返回匹配ID
I can count the final price using aggregate, but this return all document in a collection, how to make it return only the matches ids
"_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)
}
})
,如果我添加此$in
查询,它将返回空数组
and if i add this $in
query, it returns empty array
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)
}
})
推荐答案
您的ids
变量将由字符串"而不是ObjectId
值构成.
Your ids
variable will be constructed of "strings", and not ObjectId
values.
在常规查询中,将ObjectId
的猫鼬自动广播"字符串值转换为正确的类型,但这不会在聚合管道中发生,如问题#1399中所述.
Mongoose "autocasts" string values for ObjectId
into their correct type in regular queries, but this does not happen in the aggregation pipeline, as in described in issue #1399.
相反,您必须进行正确的强制转换才能手动键入:
Instead you must do the correct casting to type manually:
ids = ids.map(function(el) { return mongoose.Types.ObjectId(el) })
然后,您可以在管道阶段使用它们:
Then you can use them in your pipeline stage:
{ "$match": { "_id": { "$in": ids } } }
原因是因为聚合管道通常"会更改文档结构,因此猫鼬不假定架构"在任何给定的管道阶段都适用于文档.
The reason is because aggregation pipelines "typically" alter the document structure, and therefore mongoose makes no presumption that the "schema" applies to the document in any given pipeline stage.
有争议的是,当它是一个$match
阶段时,第一个"管道阶段应该执行此操作,因为实际上该文档没有被更改.但是现在这还不是怎么回事.
It is arguable that the "first" pipeline stage when it is a $match
stage should do this, since indeed the document is not altered. But right now this is not how it happens.
任何可能是字符串"或至少不是正确的BSON类型的值都需要手动进行强制转换才能匹配.
Any values that may possibly be "strings" or at least not the correct BSON type need to be manually cast in order to match.
这篇关于Moongoose合计$ match与ID的不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!