Pat*_*Pat 5 mongoose mongodb node.js express
我正在尝试获取一系列未付款订单。订单子文档有一个属性isPaid,定义订单是否已付款。
在我看来,我只想显示尚未付款的订单。
这是我的架构:
var order = new Schema({
content: [{
product: {type: String, required: true},
quantity: {type: Number},
vatRate: {type: Number, required: true},
price: {type: Number}
}],
isPaid: {type: Boolean, default: false},
number: {type: Number}
});
var clientSchema = new Schema({
[...]
information: {
code: {type: String, required: true},
name: {type: String, required: true}
},
orders: [order],
[...]
});
Run Code Online (Sandbox Code Playgroud)
我开始了,但没有成功
clientModel.find(
{
"information.code": clientCode,
"orders.isPaid": false
}, function (err, client) { ... });
Run Code Online (Sandbox Code Playgroud)
然后,我做了很多尝试,有成功$all,$elemMatch也没有成功。大多数时候,它会返回所有已付款或未付款的订单。我不知道为什么。我需要一些帮助,请:)
您可以采取的一种方法是使用聚合框架来获取所需的数组。考虑以下管道,它首先使用$match运算符来过滤将进入下一阶段(步骤)的文档$project。这只产生所需的订单数组,该数组将使用子文档上的$filter比较运算符进行过滤,并且应用过滤器的条件使用。$eqisPaid
最终管道将如下所示:
const pipeline = [
{ '$match': {
'information.code': clientCode,
'orders.isPaid': false
} },
{ '$project': {
'orders': {
'$filter': {
'input': '$orders',
'cond': {
'$eq': ['$$this.isPaid', false]
}
}
}
} }
]
Run Code Online (Sandbox Code Playgroud)
或者如果 MongoDB 服务器版本不支持$filter(较旧的驱动程序),则初始匹配后的下一步将是
$unwind.
此步骤从输入文档解构订单数组字段,以输出每个元素的文档。每个输出文档都是输入文档,其中数组字段的值被元素替换。
下一步使用$match运算符对解构的子文档进行进一步过滤,然后将其$group按标识符_id表达式进行分组(使用 ),并将累加器表达式$push(在订单子文档上)应用于返回所需数组的每个组。
const pipeline = [
{ '$match': {
'information.code': clientCode,
'orders.isPaid': false
} },
{ '$unwind': '$orders' },
{ '$match': {
'orders.isPaid': false
} },
{ '$group': {
'_id': '$_id',
'orders': {
'$push': '$orders'
}
} }
]
clientModel.aggregate(pipeline).exec(function (err, res){
if (err) return handleError(err);
console.log(res); // [ { orders: [...] } ]
});
Run Code Online (Sandbox Code Playgroud)
或者使用聚合管道构建器:
clientModel.aggregate()
.match({'information.code': clientCode, 'orders.isPaid': false})
.project({
'orders': {
'$filter': {
'input': '$orders',
'cond': {
'$eq': ['$$this.isPaid', false]
}
}
}
})
.exec(function (err, res) {
if (err) return handleError(err);
console.log(res); // [ { orders: [...] } ]
});
Run Code Online (Sandbox Code Playgroud)
或者对于旧版本
clientModel.aggregate()
.match({'information.code': clientCode, 'orders.isPaid': false})
.unwind('orders')
.match({'orders.isPaid': false })
.group({'_id': '$_id', 'orders': { '$push': '$orders' } })
.select('-_id orders')
.exec(function (err, res) {
if (err) return handleError(err);
console.log(res); // [ { orders: [...] } ]
});
Run Code Online (Sandbox Code Playgroud)