MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

सशर्त रूप से एकत्रीकरण पाइपलाइन चरणों को शामिल करें

आप जो करना चाहते हैं वह प्रदान किए गए विकल्पों के आधार पर पूरी पाइपलाइन का निर्माण करना है। यह' आख़िरकार केवल एक डेटा संरचना है।

आप "सरणी" के लिए गलत तरीके से परीक्षण कर रहे हैं और आपको 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"
        }
    }
]

जहां यदि आपको फ़िल्टर करने की आवश्यकता नहीं है, तो आप बस अतिरिक्त पाइपलाइन चरण को छोड़ दें।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoShell में:मेरे संग्रह से कनेक्ट करने में सक्षम नहीं, db.collection_name वापसी NaN

  2. मोंगोडब क्वेरी अनुकूलन में शामिल हों

  3. मॉडलिंग मोंगोडब .net कोर में संदर्भित संबंधों को संग्रहीत करता है

  4. MongoDB में लिफ्ट स्टोर BigDecimal

  5. एक JSON फ़ाइल में MongoDB संग्रह निर्यात करें