आप प्रत्येक मान को "इन" और "आउट" के लिए "टाइप" द्वारा प्रविष्टियों की एक सरणी में अनिवार्य रूप से जोड़कर, स्रोत पर दस्तावेज़ों को विभाजित कर सकते हैं। आप इसे केवल $map
का उपयोग करके कर सकते हैं
और $cond
फ़ील्ड चुनने के लिए, फिर $unwind
सरणी और फिर <के साथ निरीक्षण करके निर्धारित करें कि किस क्षेत्र को फिर से "गिनना" है कोड>$cond
:
collection.aggregate([
{ "$project": {
"dates": {
"$filter": {
"input": {
"$map": {
"input": [ "in", "out" ],
"as": "type",
"in": {
"type": "$$type",
"date": {
"$cond": {
"if": { "$eq": [ "$$type", "in" ] },
"then": "$inDate",
"else": "$outDate"
}
}
}
}
},
"as": "dates",
"cond": { "$ne": [ "$$dates.date", null ] }
}
}
}},
{ "$unwind": "$dates" },
{ "$group": {
"_id": {
"year": { "$year": "$dates.date" },
"month": { "$month": "$dates.date" },
"day": { "$dayOfMonth": "$dates.date" }
},
"countIn": {
"$sum": {
"$cond": {
"if": { "$eq": [ "$dates.type", "in" ] },
"then": 1,
"else": 0
}
}
},
"countOut": {
"$sum": {
"$cond": {
"if": { "$eq": [ "$dates.type", "out" ] },
"then": 1,
"else": 0
}
}
}
}}
])
ऐसा करने का यह एक सुरक्षित तरीका है जो बीएसओएन सीमा को तोड़ने का जोखिम नहीं उठाता है, चाहे आप उस पर कितना भी डेटा भेजें।
व्यक्तिगत रूप से मैं अलग प्रक्रियाओं के रूप में चलाऊंगा और समेकित परिणामों को अलग से "गठबंधन" करूंगा, लेकिन यह उस वातावरण पर निर्भर करेगा जिसमें आप चल रहे हैं, जिसका उल्लेख प्रश्न में नहीं किया गया है।
"समानांतर" निष्पादन के उदाहरण के लिए, आप उल्का में कहीं इन पंक्तियों के साथ संरचना कर सकते हैं:
import { Meteor } from 'meteor/meteor';
import { Source } from '../imports/source';
import { Target } from '../imports/target';
Meteor.startup(async () => {
// code to run on server at startup
await Source.remove({});
await Target.remove({});
console.log('Removed');
Source.insert({
"_id" : "XBpNKbdGSgGfnC2MJ",
"po" : 72134185,
"machine" : 40940,
"location" : "02A01",
"inDate" : new Date("2017-07-19T06:10:13.059Z"),
"requestDate" : new Date("2017-07-19T06:17:04.901Z"),
"outDate" : new Date("2017-07-19T06:30:34Z")
});
console.log('Inserted');
await Promise.all(
["In","Out"].map( f => new Promise((resolve,reject) => {
let cursor = Source.rawCollection().aggregate([
{ "$match": { [`${f.toLowerCase()}Date`]: { "$exists": true } } },
{ "$group": {
"_id": {
"year": { "$year": `$${f.toLowerCase()}Date` },
"month": { "$month": `$${f.toLowerCase()}Date` },
"day": { "$dayOfYear": `$${f.toLowerCase()}Date` }
},
[`count${f}`]: { "$sum": 1 }
}}
]);
cursor.on('data', async (data) => {
cursor.pause();
data.date = data._id;
delete data._id;
await Target.upsert(
{ date: data.date },
{ "$set": data }
);
cursor.resume();
});
cursor.on('end', () => resolve('done'));
cursor.on('error', (err) => reject(err));
}))
);
console.log('Mapped');
let targets = await Target.find().fetch();
console.log(targets);
});
जो अनिवार्य रूप से लक्ष्य संग्रह में आउटपुट करने जा रहा है जैसा कि टिप्पणियों में उल्लेख किया गया था:
{
"_id" : "XdPGMkY24AcvTnKq7",
"date" : {
"year" : 2017,
"month" : 7,
"day" : 200
},
"countIn" : 1,
"countOut" : 1
}