Your function findOneBy
is asynchronous. As your code loops through the array of results stored in items
, each one is triggering an asynchronous look up.
However, before all of those return, you're sending the results to the client via `res.send(results). So, while the data is returned to the Node.JS application, it's after the results have already been sent.
There are a few ways to handle this, but I'd suggest you consider logic more like this (pseudo-code, as I don't have a DB mirroring your data):
collection.find({}, criteria).toArray(function(err, items) {
var allLogIds = [];
var logIdsByUse = {};
Object.keys(items).forEach(function(logIndex) {
// here, we'll first bit a list of all LogIds
var trace = items[logIndex];
allLogIds.push(trace.LogId);
// now build a index of logId and a list of dependent objects
logIdsByUse[trace.LogId] = [] || logIdsByUse[trace.LogId];
logIdsByUse[trace.LogId].push(trace);
});
// now that the LogIds are all gathered, we'll do a search for all of them
// at once.
// *** You should make certain that the LogId field is indexed or this will
// *** never perform adequately in any situation
db.collection("log", function(err, collection) {
if (err) { /* do something with the error, maybe 500 error */ }
else {
collection.find({ LogId: { $in : allLogIds}})
.toArray(function(err, logs) {
logs.forEach(function(log) {
// grab the LogId,
// get the array of traces that use the LogId
// from the logIdsByUse[LogId]
// loop through that array, and do the fix up that you
// want
});
// now, you may send the results
results['total'] = count;
results['results'] = items.length;
results['rows'] = items;
res.send(results);
});
});
});
You could also look at using one of the async libraries for Node.JS, but it won't significantly change what you need to do.