Moongoose合计$ match与ID的不匹配 [英] Moongoose aggregate $match does not match id's

查看:99
本文介绍了Moongoose合计$ match与ID的不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想按ID(56e641d4864e5b780bb992c656e65504a323ee0812e511f2)显示产品,并在扣除折扣后显示价格(如果有).

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的不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆