आप जो करना चाहते हैं वह प्रदान किए गए विकल्पों के आधार पर पूरी पाइपलाइन का निर्माण करना है। यह' आख़िरकार केवल एक डेटा संरचना है।
आप "सरणी" के लिए गलत तरीके से परीक्षण कर रहे हैं और आपको instanceof
क्योंकि typeof
वास्तव में "ऑब्जेक्ट"
return लौटाएगा और नहीं "सरणी"
।
इसके अलावा आप वास्तव में उस स्थिति को पहले . में चाहते हैं के बाद जोड़े जाने के अलावा, दस्तावेज़ों का बेहतर चयन करने के लिए पाइपलाइन चरण $अनविंड
जहां जरूरत हो:
var pipeline = [
{ $match:
Object.assign(
{ 'shop.nameSlug' : req.query.nameSlug },
(req.query.status)
? { "status.status": (req.query.status instanceof Array)
? { "$in": req.query.status } : req.query.status }
: {}
)
},
{ $unwind: "$status" },
...(
(req.query.status)
? [{ "$match": {
"status.status": (req.query.status instanceof Array)
? { "$in": req.query.status } : req.query.status
}}]
: []
),
{ $group: {
_id: "$_id",
status: { $addToSet: "$status" },
number: { $first: "$number" },
date: { $first: "$date" },
comment: { $first: "$comment" }
}}
];
Order.aggregate(pipeline).exec(function(err, orders){
})
एक अनुरोध
दिया गया है स्थिति
. में मौजूद किसी वस्तु के साथ वस्तु आपको मिलता है:
// Example stucture
var req = {
query: {
nameSlug: "Bill",
status: "A"
},
};
// Pipeline output as:
[
{
"$match" : {
"shop.nameSlug" : "Bill",
"status.status" : "A"
}
},
{
"$unwind" : "$status"
},
{
"$match" : {
"status.status" : "A"
}
},
{
"$group" : {
"_id" : "$_id",
"status" : {
"$addToSet" : "$status"
},
"number" : {
"$first" : "$number"
},
"date" : {
"$first" : "$date"
},
"comment" : {
"$first" : "$comment"
}
}
}
]
एक सरणी के साथ:
var req = {
query: {
nameSlug: "Bill",
status: ["A","B"]
},
};
// Pipeline output as:
[
{
"$match" : {
"shop.nameSlug" : "Bill",
"status.status" : {
"$in" : [
"A",
"B"
]
}
}
},
{
"$unwind" : "$status"
},
{
"$match" : {
"status.status" : {
"$in" : [
"A",
"B"
]
}
}
},
{
"$group" : {
"_id" : "$_id",
"status" : {
"$addToSet" : "$status"
},
"number" : {
"$first" : "$number"
},
"date" : {
"$first" : "$date"
},
"comment" : {
"$first" : "$comment"
}
}
}
]
और कुछ नहीं के साथ:
var req = {
query: {
nameSlug: "Bill",
//status: ["A","B"]
},
};
// Pipeline output as:
[
{
"$match" : {
"shop.nameSlug" : "Bill"
}
},
{
"$unwind" : "$status"
},
{
"$group" : {
"_id" : "$_id",
"status" : {
"$addToSet" : "$status"
},
"number" : {
"$first" : "$number"
},
"date" : {
"$first" : "$date"
},
"comment" : {
"$first" : "$comment"
}
}
}
]
तो आप देख सकते हैं कि प्रदान किए गए मूल्यों के आधार पर भागों को सशर्त रूप से शामिल किया गया है।
$filter का उपयोग करना
आपको वास्तव में $filter
का उपयोग करना चाहिए
इसके बजाय यहाँ। यह $unwind
से कहीं अधिक कुशल है
और आप वास्तव में कुछ भी समूहीकृत नहीं कर रहे हैं। आप वास्तव में फ़िल्टर किए गए सरणी चाहते हैं। तो आप सशर्त रूप से बस इतना ही जोड़ें:
var pipeline = [
{ $match:
Object.assign(
{ 'shop.nameSlug' : req.query.nameSlug },
(req.query.status)
? { "status.status": (req.query.status instanceof Array)
? { "$in": req.query.status } : req.query.status }
: {}
)
},
...(
(req.query.status)
? [{ "$addFields": {
"status": {
"$filter": {
"input": "$status",
"cond": {
[(req.query.status instanceof Array) ? "$in" : "$eq"]:
[ "$$this.status", req.query.status ]
}
}
}
}}]
: []
)
];
विकल्प $in
के बीच है
और $eq
तुलना परीक्षण के लिए, जो आपूर्ति की जाती है उसके आधार पर। आप वैकल्पिक रूप से पूरी चीज़ को $setUnion
यदि आप परिणाम में "सेट" का उपयोग करने के लिए "वास्तव में मतलब" हैं। लेकिन आम तौर पर ऐसा लगता है कि आप केवल सरणी से मानों को "फ़िल्टर" करना चाहते हैं।
एक ही मूल्य की समान अपेक्षाओं के साथ:
var req = {
query: {
nameSlug: "Bill",
//status: ["A","B"]
status: "A"
},
};
/* 1 */
[
{
"$match" : {
"shop.nameSlug" : "Bill",
"status.status" : "A"
}
},
{
"$addFields" : {
"status" : {
"$filter" : {
"input" : "$status",
"cond" : {
"$eq" : [
"$$this.status",
"A"
]
}
}
}
}
}
]
एक सरणी:
var req = {
query: {
nameSlug: "Bill",
status: ["A","B"]
},
};
/* 1 */
[
{
"$match" : {
"shop.nameSlug" : "Bill",
"status.status" : {
"$in" : [
"A",
"B"
]
}
}
},
{
"$addFields" : {
"status" : {
"$filter" : {
"input" : "$status",
"cond" : {
"$in" : [
"$$this.status",
[
"A",
"B"
]
]
}
}
}
}
}
]
या कुछ नहीं:
var req = {
query: {
nameSlug: "Bill",
//status: ["A","B"]
},
};
/* 1 */
[
{
"$match" : {
"shop.nameSlug" : "Bill"
}
}
]
जहां यदि आपको फ़िल्टर करने की आवश्यकता नहीं है, तो आप बस अतिरिक्त पाइपलाइन चरण को छोड़ दें।