MongoDB एग्रीगेशन में $unwind और $group का उपयोग करके नेस्टेड ऐरे की सभी एलिमेंट्स शर्त जांचना
MongoDB में किसी दस्तावेज़ के नेस्टेड ऐरे के सभी एलिमेंट्स एक शर्त पूरी करते हैं यह जांचने के लिए, ऐरे को अनविंड करें, ग्रुप करके गिनती करें, फिर तुलना करें।
उदाहरण: संग्रह और दस्तावेज़ बनाना
> db.demo418.insertOne({
"details":[
{"CountryName":"US","Marks":45},
{"CountryName":"US","Marks":56}
],
"Name":"John"
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e724324b912067e57771ae6") }
> db.demo418.insertOne({
"details":[
{"CountryName":"US","Marks":78},
{"CountryName":"UK","Marks":97}
],
"Name":"Mike"
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e724325b912067e57771ae7") }
सभी दस्तावेज़ देखना
> db.demo418.find();
आउटपुट:
{ "_id" : ObjectId("5e724324b912067e57771ae6"), "details" : [ { "CountryName" : "US", "Marks" : 45 }, { "CountryName" : "US", "Marks" : 56 } ], "Name" : "John" }
{ "_id" : ObjectId("5e724325b912067e57771ae7"), "details" : [ { "CountryName" : "US", "Marks" : 78 }, { "CountryName" : "UK", "Marks" : 97 } ], "Name" : "Mike" }
सभी details एलिमेंट्स में CountryName == "US" वाले दस्तावेज़ फ़िल्टर करना
> db.demo418.aggregate([
{$unwind:"$details"},
{ $group: {
_id: '$_id',
details : { $first: '$details' },
alldetails: { $sum: 1 },
alldetailsmatch: { $sum: { $cond: [ { $eq: [ '$details.CountryName', "US" ] }, 1, 0 ] } },
Name: { $first: '$Name' }
}},
{ $project: {
_id: 1,
Name: 1,
details: 1,
arrayValue: { $cond: [ { $eq: [ '$alldetails', '$alldetailsmatch' ] }, 1, 0 ] }
}},
{ $match: { 'arrayValue' : 1 } }
])
आउटपुट:
{ "_id" : ObjectId("5e724324b912067e57771ae6"), "details" : { "CountryName" : "US", "Marks" : 45 }, "Name" : "John", "arrayValue" : 1 }
व्याख्या:
$unwind: "$details"- ऐरे के प्रत्येक एलिमेंट के लिए अलग दस्तावेज़ बनाता है$group- मूल _id द्वारा पुनः ग्रुप करता है:alldetails- कुल एलिमेंट्स की गिनतीalldetailsmatch- शर्त पूरी करने वाले एलिमेंट्स की गिनती
$project-arrayValueफील्ड बनाता है: दोनों गिनती बराबर हैं तो 1$match- केवलarrayValue: 1वाले दस्तावेज़ रखता है
सरल विकल्प (MongoDB 3.6+): $all ऑपरेटर या $not + $elemMatch
// सभी एलिमेंट्स US हैं (कोई गैर-US नहीं)
db.demo418.find({
"details.CountryName": { $not: { $elemMatch: { $ne: "US" } } }
})
// या एग्रीगेशन में $allElementsTrue
db.demo418.aggregate([
{ $match: {
$expr: {
$allElementsTrue: {
$map: { input: "$details", as: "d", in: { $eq: ["$$d.CountryName", "US"] } }
}
}
}}
])