![](/img/trans.png)
[英]How can I create a mongoose virtual field that lists the length of a subdocument?
[英]How can I filter by subdocument field in a mongoose aggregation?
我想過濾支付訂單的特定用戶的費用。 這是我的模式:
var PaymentOrderSchema = new Schema({
name: {type: String, required: true},
description: {type: String},
amount: {type: Number},
charges: [{type: Schema.Types.ObjectId, ref: 'Charge'}],
},
var ChargeSchema = new Schema({
amount: {type: Number},
user: {type: Schema.Types.ObjectId, ref: 'User'},
status: {type: String},
description: {type: String},
creation_date:{type: Date}
}
我正在嘗試使用聚合,但我無法過濾費用。 當我使用 $ne 而不是 $eq 時,它確實會向我退還費用,所以我知道我走在正確的軌道上。 這是我的實際代碼:
const paymentOrder = await PaymentOrder.aggregate([
{$match: {'_id': mongoose.Types.ObjectId(req.query.payment_order_id)}},
{$project: {
charges: {$filter: {
input: '$charges',
as: 'charge',
cond: {$eq: ['$$charge.user._id', mongoose.Types.ObjectId(req.user._id)]}
}}
}}
]);
謝謝!
如果我正確理解您的要求,那么我們可以將 $lookup 與管道一起使用
像這樣的東西
db.paymentOrder.aggregate([
{
$match: {
_id: ObjectId("5a934e000102030405000003") // replace this hard-coded objectId with mongoose.Types.ObjectId(req.query.payment_order_id)
}
},
{
$lookup: {
from: "charge",
let: {
chargeIds: "$charges"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$user",
"userId1" // replace this with mongoose.Types.ObjectId(req.user._id)
]
}
}
}
],
as: "charges"
}
}
])
檢查這個Mongo Plaground
希望能幫助到你
聚合在數據庫服務器上運行,而引用由客戶端的驅動程序擴展,因此在管道中實際看到的值是
DBRef("User",ObjectId(...),"DatabaseName")
可以訪問類似於 object
{"$ref":"User", "$id":ObjectId(...), "$db":"DatabaseName"}
但這又引發了一個問題:字段名稱不允許以$
開頭,所以這將引發錯誤:
{$eq:["$$charge.user.$id",mongoose.Types.ObjectId(req.user._id)]}
因此,您可以跳過聚合中的該步驟並將文檔帶回 mongoose 進行填充,或者如果您只需要匹配$id
,您可以使用$objectToArray
分解 DBRef 以便您可以匹配:
{$match: {'_id': mongoose.Types.ObjectId(req.query.payment_order_id)}},
{$unwind: "$charges"},
{$addFields: {charges:{$objectToArray:"$charges"}}},
{$match: {charges:{
$elemMatch:{k:"$id",v:mongoose.Types.ObjectId(req.user._id}
}}},
{$group:{_id:"$_id", charges:{$push:{$arrayToObject("$charges"}}}}}
這將返回可以由驅動程序擴展的 DBRef,但這與charges
文檔的_id
匹配,這可能不是您想要的。
然而,一旦你有了收費文檔的_id
,你可以使用$lookup
然后過濾它們,但是我們還必須處理作為 DBref 的user
:
{$match: {'_id': mongoose.Types.ObjectId(req.query.payment_order_id)}},
{$unwind: "$charges"},
{$addFields: {chargeId:{$filter:{
input:$objectToArray:"$charges"
cond:{$eq:["$$this.k","$id"]}
}}}},
{$lookup:{
from:"charge",
localField:"$chargeId.v",
foreignField:"$_id",
as: charges
}},
{$unwind:"$charges"},
{$addField:{chargeUser:{$filter:{
input:{$objectToArray:"$charges.user"},
cond:{$eq:["$$this.k","$id"]}
}}}},
{$match: {"chargeUser.v":mongoose.Types.ObjectId(req.user._id)}},
{$project:{
chargeUser:0,
chargeId:0
},
{$group:{
_id:"$_id",
document:{$first:"$$ROOT"},
charges:{$push:"$charges"}
}},
{$addFields:{"document.charges":"$charges"}},
{$replaceRoot:{newRoot:"$document"}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.