आप उन्हें अद्यतन करके अपने दस्तावेज़ संरचना को बदलने की जरूरत है। .forEach
विधि का उपयोग करके प्रत्येक दस्तावेज़ के माध्यम से आपको लूप की आवश्यकता होगी $unset
सभी फ़ील्ड का नाम जो product_
से शुरू होता है। वहां से आपको products
नए फ़ील्ड जोड़ने की आवश्यकता होगी जो $set
अद्यतन ऑपरेटर का उपयोग कर उत्पादों की सरणी है। कहा जा रहा है कि आप अधिकतम दक्षता के लिए अपने दस्तावेज़ों को अद्यतन करने के "bulk" संचालन का उपयोग करना चाहिए
var bulkOp = db.collection.initializeOrderedBulkOp();
var count = 0;
db.collection.find().forEach(function(doc) {
var allproducts = [];
for(var key in doc) {
if(Object.prototype.hasOwnProperty.call(doc, key) && /^product_\d+/.test(key)) {
var product = {};
product["name"] = key;
product["orderCancelled"] = doc[key]["orderCancelled"];
product["orderDelivered"] = doc[key]["orderDelivered"];
allproducts.push(product);
var unsetField = {};
unsetField[key] = "";
bulkOp.find({"_id": doc._id}).update({ "$unset": unsetField });
};
count++;
};
bulkOp.find({"_id": doc._id}).update({
"$set": { "products": allproducts }
});
count++;
if(count % 500 === 0) {
// Execute per 500 operations and re-init
bulkOp.execute();
bulkOp = db.collection.initializeOrderedBulkOp();
}
})
// clean up queues
if(count > 0) {
bulkOp.execute();
}
आपके दस्तावेज़ अब इस तरह दिखेगा:
{
"_id" : NumberLong(542),
"products" : [
{
"name" : "product_1",
"orderCancelled" : 0,
"orderDelivered" : 6
},
{
"name" : "product_2",
"orderCancelled" : 3,
"orderDelivered" : 16
},
{
"name" : "product_3",
"orderCancelled" : 5,
"orderDelivered" : 11
}
]
}
फिर .aggregate()
पद्धति का उपयोग करके अपने एकत्रीकरण क्वेरी आता है:
db.collection.aggregate([
{ "$match": { "_id": 542 } },
{ "$unwind": "$products" },
{ "$group": {
"_id": "$_id",
"maxOrderCancelled": { "$max": "$products.orderCancelled"},
"minOrderDelivvered": { "$min": "$products.orderDelivered"}
}}
])
कौन सा रिटर्न:
{ "_id" : NumberLong(542), "maxOrderCancelled" : 5, "minOrderDelivvered" : 6 }
version 3.2 से आप $max
और $min
अपने $project
चरण में जो यह करने के लिए एक और अधिक बेहतर तरीके से उपयोग कर सकते हैं क्योंकि वहाँ $unwind
पहली बार अपने सरणी के लिए कोई जरूरत नहीं।
db.collection.aggregate([
{ "$match": { "_id": 542 } },
{ "$project": {
"maxOrderCancelled": {
"$max": {
"$map": {
"input": "$products",
"as": "order",
"in": "$$orc.orderCancelled"
}
}
},
"minOrderDelivered": {
"$min": {
"$map": {
"input": "$products",
"as": "orc",
"in": "$$orc.orderDelivered"
}
}
}
}}
])
कौन सा पैदावार:
{ "_id" : NumberLong(542), "maxOrderCancelled" : 5, "minOrderDelivered" : 6 }
क्यों नहीं आप अपने उत्पादों को एक सरणी में रख सकता हूं? –
@DmytroShevchenko मैं तुम्हें नहीं मिला था। दरअसल एक दूसरे मामले में मैं 'ऑर्डर डिलीवरेड' के लिए 'उत्पाद नाम' द्वारा गिनती भी दे सकता हूं। वैसे आपके मामले में डिजाइन क्या होगा? – Shams
कृपया मेरे उत्तर में डेटा संरचना का उदाहरण देखें। क्या आप 'उत्पाद नाम' द्वारा 'ऑर्डर डिलीवरेड' के लिए गिनती से क्या मतलब बता सकते हैं? –