Mongodb Moongoose聚合$match与id';s

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

我想通过ID(
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
    。聚合管道不使用
    模式
    ,实际上我已经解释过了;唉。。我在我的模式静态方法中创建了一个lamda
    const castUserId=(userId)=>mongoose.Types.ObjectId(userId)
    现在我很高兴……在这个问题上浪费了几个小时……感谢您的解决方案,它现在可以工作了。但通常我在findOneAndUpdate或其他查询中将id作为字符串抛出,效果很好,问题只会在聚合中发生吗?@MuhammadFasalirRahman这正是我的回答。
    .find()
    可以使用
    模式
    ,对于
    \u id
    字段,该模式的默认类型当然是
    ObjectId
    。聚合管道不使用
    模式
    ,实际上我已经解释过了;唉。。我在我的模式静态方法中创建了一个lamda
    const castUserId=(userId)=>mongoose.Types.ObjectId(userId)