MongoDB प्रश्नों के साथ किसी भी प्रकार का "ग्रुपिंग" करने के लिए आप एग्रीगेशन फ्रेमवर्क या मैपरेडस का उपयोग करने में सक्षम होना चाहते हैं। एकत्रीकरण ढांचे को आम तौर पर पसंद किया जाता है क्योंकि यह जावास्क्रिप्ट अनुवाद के बजाय देशी कोडित ऑपरेटरों का उपयोग करता है, और इसलिए यह आमतौर पर तेज़ होता है।
एग्रीगेशन स्टेटमेंट केवल सर्वर एपीआई साइड पर चलाया जा सकता है, जो समझ में आता है क्योंकि आप क्लाइंट पर ऐसा नहीं करना चाहेंगे। लेकिन यह वहां किया जा सकता है और ग्राहक को परिणाम उपलब्ध करा सकता है।
परिणाम प्रकाशित करने के तरीके प्रदान करने के लिए इस उत्तर को श्रेय के साथ:
Meteor.publish("cardLikesDislikes", function(args) {
var sub = this;
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var pipeline = [
{ "$group": {
"_id": "$card_id",
"likes": {
"$sum": {
"$cond": [
{ "$eq": [ "$vote", 1 ] },
1,
0
]
}
},
"dislikes": {
"$sum": {
"$cond": [
{ "$eq": [ "$vote", 2 ] },
1,
0
]
}
},
"total": {
"$sum": {
"$cond": [
{ "$eq": [ "$vote", 1 ] },
1,
-1
]
}
}
}},
{ "$sort": { "total": -1 } }
];
db.collection("server_collection_name").aggregate(
pipeline,
// Need to wrap the callback so it gets called in a Fiber.
Meteor.bindEnvironment(
function(err, result) {
// Add each of the results to the subscription.
_.each(result, function(e) {
// Generate a random disposable id for aggregated documents
sub.added("client_collection_name", Random.id(), {
card: e._id,
likes: e.likes,
dislikes: e.dislikes,
total: e.total
});
});
sub.ready();
},
function(error) {
Meteor._debug( "Error doing aggregation: " + error);
}
)
);
});
सामान्य एकत्रीकरण विवरण केवल एक $group
होता है "card_id" की एकल कुंजी पर संचालन। "पसंद" और "नापसंद" प्राप्त करने के लिए आप एक "सशर्त अभिव्यक्ति" का उपयोग करते हैं जो $cond
है ।
यह एक "टर्नरी" ऑपरेटर है जो "वोट" के मूल्य पर एक तार्किक परीक्षण पर विचार करता है, और जहां यह अपेक्षित प्रकार से मेल खाता है तो एक सकारात्मक 1
लौटा दिया जाता है, अन्यथा यह 0
है ।
फिर वे मान संचायक को भेजे जाते हैं जो $sum
. है उन्हें एक साथ जोड़ने के लिए, और प्रत्येक "card_id" के लिए "पसंद" या "नापसंद" द्वारा कुल गणना उत्पन्न करें।
"कुल" के लिए, सबसे प्रभावी तरीका "पसंद" के लिए "सकारात्मक" मान और समूहीकरण करते समय "नापसंद" के लिए एक नकारात्मक मान देना है। एक $add
है ऑपरेटर, लेकिन इस मामले में इसके उपयोग के लिए एक और पाइपलाइन चरण की आवश्यकता होगी। इसलिए हम इसे इसके बजाय केवल एक ही मंच पर करते हैं।
इसके अंत में एक $sort
है "अवरोही" क्रम में इसलिए सबसे बड़ी सकारात्मक वोट गणना शीर्ष पर है। यह वैकल्पिक है और आप केवल डायनेमिक सॉर्टिंग क्लाइंट साइड का उपयोग करना चाह सकते हैं। लेकिन यह एक डिफ़ॉल्ट के लिए एक अच्छी शुरुआत है जो ऐसा करने के ऊपरी हिस्से को हटा देता है।
तो वह एक सशर्त एकत्रीकरण कर रहा है और परिणामों के साथ काम कर रहा है।
टेस्ट लिस्टिंग
यह मैंने एक नव निर्मित उल्का परियोजना के साथ परीक्षण किया, जिसमें कोई एडिन नहीं है और केवल एक टेम्पलेट और जावास्क्रिप्ट फ़ाइल है
कंसोल कमांड
meteor create cardtest
cd cardtest
meteor remove autopublish
प्रश्न में पोस्ट किए गए दस्तावेज़ों के साथ डेटाबेस में "कार्ड" संग्रह बनाया गया। और फिर नीचे दी गई सामग्री के साथ डिफ़ॉल्ट फ़ाइलों को संपादित किया:
cardtest.js
Cards = new Meteor.Collection("cardStore");
if (Meteor.isClient) {
Meteor.subscribe("cards");
Template.body.helpers({
cards: function() {
return Cards.find({});
}
});
}
if (Meteor.isServer) {
Meteor.publish("cards",function(args) {
var sub = this;
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var pipeline = [
{ "$group": {
"_id": "$card_id",
"likes": { "$sum": { "$cond": [{ "$eq": [ "$vote", 1 ] },1,0] } },
"dislikes": { "$sum": { "$cond": [{ "$eq": [ "$vote", 2 ] },1,0] } },
"total": { "$sum": { "$cond": [{ "$eq": [ "$vote", 1 ] },1,-1] } }
}},
{ "$sort": { "total": -1, "_id": 1 } }
];
db.collection("cards").aggregate(
pipeline,
Meteor.bindEnvironment(
function(err,result) {
_.each(result,function(e) {
e.card_id = e._id;
delete e._id;
sub.added("cardStore",Random.id(), e);
});
sub.ready();
},
function(error) {
Meteor._debug( "error running: " + error);
}
)
);
});
}
cardtest.html
<head>
<title>cardtest</title>
</head>
<body>
<h1>Card aggregation</h1>
<table border="1">
<tr>
<th>Card_id</th>
<th>Likes</th>
<th>Dislikes</th>
<th>Total</th>
</tr>
{{#each cards}}
{{> card }}
{{/each}}
</table>
</body>
<template name="card">
<tr>
<td>{{card_id}}</td>
<td>{{likes}}</td>
<td>{{dislikes}}</td>
<td>{{total}}</td>
</tr>
</template>
अंतिम एकत्रित संग्रह सामग्री:
[
{
"_id":"Z9cg2p2vQExmCRLoM",
"likes":3,
"dislikes":1,
"total":2,
"card_id":1
},
{
"_id":"KQWCS8pHHYEbiwzBA",
"likes":2,
"dislikes":0,
"total":2,
"card_id":2
},
{
"_id":"KbGnfh3Lqcmjow3WN",
"likes":1,
"dislikes":0,
"total":1,
"card_id":3
}
]