"EndpointId"
. में "अद्वितीय" घटनाओं की गणना करने के लिए क्वेरी प्रत्येक "Uid"
. का "Tags"
. में और "Type"
"Sensors"
. में होगा:
db.collection.aggregate([
{ "$unwind": "$Tags" },
{ "$unwind": "$Tags.Sensors" },
{ "$group": {
"_id": {
"EndpointId": "$EndpointId",
"Uid": "$Tags.Uid",
"Type": "$Tags.Sensors.Type"
},
}},
{ "$group": {
"_id": {
"EndpointId": "$_id.EndpointId",
"Uid": "$_id.Uid",
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.EndpointId",
"tagCount": { "$sum": 1 },
"sensorCount": { "$sum": "$count" }
}}
])
या सी#
. के लिए var results = collection.AsQueryable()
.SelectMany(p => p.Tags, (p, tag) => new
{
EndpointId = p.EndpointId,
Uid = tag.Uid,
Sensors = tag.Sensors
}
)
.SelectMany(p => p.Sensors, (p, sensor) => new
{
EndpointId = p.EndpointId,
Uid = p.Uid,
Type = sensor.Type
}
)
.GroupBy(p => new { EndpointId = p.EndpointId, Uid = p.Uid, Type = p.Type })
.GroupBy(p => new { EndpointId = p.Key.EndpointId, Uid = p.Key.Uid },
(k, s) => new { Key = k, count = s.Count() }
)
.GroupBy(p => p.Key.EndpointId,
(k, s) => new
{
EndpointId = k,
tagCount = s.Count(),
sensorCount = s.Sum(x => x.count)
}
);
कौन सा आउटपुट:
{
"EndpointId" : "89799bcc-e86f-4c8a-b340-8b5ed53caf83",
"tagCount" : 4,
"sensorCount" : 16
}
हालांकि वास्तव में ऐसा करने का "सबसे कुशल" तरीका यह देखते हुए कि प्रस्तुत दस्तावेजों में "Uid"
के लिए अद्वितीय मान हैं वैसे भी $reduce
. होगा दस्तावेजों के भीतर ही राशि:
db.collection.aggregate([
{ "$group": {
"_id": "$EndpointId",
"tags": {
"$sum": {
"$size": { "$setUnion": ["$Tags.Uid",[]] }
}
},
"sensors": {
"$sum": {
"$sum": {
"$map": {
"input": { "$setUnion": ["$Tags.Uid",[]] },
"as": "tag",
"in": {
"$size": {
"$reduce": {
"input": {
"$filter": {
"input": {
"$map": {
"input": "$Tags",
"in": {
"Uid": "$$this.Uid",
"Type": "$$this.Sensors.Type"
}
}
},
"cond": { "$eq": [ "$$this.Uid", "$$tag" ] }
}
},
"initialValue": [],
"in": { "$setUnion": [ "$$value", "$$this.Type" ] }
}
}
}
}
}
}
}
}}
])
हालांकि, कथन वास्तव में LINQ के लिए अच्छी तरह से मैप नहीं करता है, इसलिए आपको BsonDocument
का उपयोग करना होगा। बयान के लिए बीएसओएन बनाने के लिए इंटरफ़ेस। और निश्चित रूप से वही "Uid"
मान "किया" वास्तव में संग्रह में कई दस्तावेज़ों के भीतर होता है, फिर $unwind
सरणी प्रविष्टियों के भीतर से दस्तावेज़ों में उन लोगों को एक साथ "समूह" करने के लिए कथन आवश्यक हैं।
मूल
आप इसे $size
प्राप्त करके हल करते हैं
सरणियों के। बाहरी सरणी के लिए यह केवल दस्तावेज़ में सरणी के फ़ील्ड पथ पर लागू होता है, और आंतरिक सरणी आइटम के लिए आपको $map
प्रत्येक "Tags"
. को संसाधित करने के लिए तत्व और फिर $size
प्राप्त करें
"Sensors"
. का और $sum
परिणामी सरणी समग्र गणना को कम करने के लिए।
प्रति दस्तावेज़ जो होगा:
db.collection.aggregate([
{ "$project": {
"tags": { "$size": "$Tags" },
"sensors": {
"$sum": {
"$map": {
"input": "$Tags",
"in": { "$size": "$$this.Sensors" }
}
}
}
}}
])
जहां आपने अपने C# कोड में कक्षाओं को असाइन किया है, वह इस प्रकार होगा:
collection.AsQueryable()
.Select(p => new
{
tags = p.Tags.Count(),
sensors = p.Tags.Select(x => x.Sensors.Count()).Sum()
}
);
वे कहाँ लौटते हैं:
{ "tags" : 3, "sensors" : 13 }
{ "tags" : 2, "sensors" : 8 }
जहां आप $group
करना चाहते हैं
परिणाम, उदाहरण के लिए पूरे संग्रह पर, तो आप यह करेंगे:
db.collection.aggregate([
/* The shell would use $match for "query" conditions */
//{ "$match": { "EndpointId": "89799bcc-e86f-4c8a-b340-8b5ed53caf83" } },
{ "$group": {
"_id": null,
"tags": { "$sum": { "$size": "$Tags" } },
"sensors": {
"$sum": {
"$sum": {
"$map": {
"input": "$Tags",
"in": { "$size": "$$this.Sensors" }
}
}
}
}
}}
])
आपके C# कोड के लिए पहले जैसा कौन सा होगा:
collection.AsQueryable()
.GroupBy(p => "", (k,s) => new
{
tags = s.Sum(p => p.Tags.Count()),
sensors = s.Sum(p => p.Tags.Select(x => x.Sensors.Count()).Sum())
}
);
वे कहाँ लौटते हैं:
{ "tags" : 5, "sensors" : 21 }
और "EndpointId
. के लिए , तो आप बस उस फ़ील्ड को null
. के बजाय समूहीकरण कुंजी के रूप में उपयोग करते हैं या 0
जैसा कि यह C# ड्राइवर मैपिंग द्वारा लागू होता है:
collection.AsQueryable()
/* Use the Where if you want a query to match only those documents */
//.Where(p => p.EndpointId == "89799bcc-e86f-4c8a-b340-8b5ed53caf83")
.GroupBy(p => p.EndpointId, (k,s) => new
{
tags = s.Sum(p => p.Tags.Count()),
sensors = s.Sum(p => p.Tags.Select(x => x.Sensors.Count()).Sum())
}
);
जो निश्चित रूप से आपके द्वारा हमें दिए गए दो दस्तावेज़ों के नमूने का समान योग है:
{ "tags" : 5, "sensors" : 21 }
तो ये बहुत ही सरल परिणाम हैं, सरल पाइपलाइन निष्पादन के साथ एक बार जब आप सिंटैक्स के लिए अभ्यस्त हो जाते हैं।
मेरा सुझाव है कि आप एग्रीगेशन ऑपरेटर्स से खुद को परिचित कर लें। मूल दस्तावेज़ीकरण से, और निश्चित रूप से "LINQ चीट शीट" सी # ड्राइवर कोड रिपॉजिटरी के साथ अभिव्यक्तियों और उनके उपयोग मानचित्रण की।
सामान्य LINQ संदर्भ भी देखें C# ड्राइवर संदर्भ में अन्य उदाहरणों के लिए कि यह सामान्य रूप से MongoDB के एकत्रीकरण ढांचे पर कैसे मैप करता है।