gpt4 book ai didi

node.js - 将更多属性附加到从 NodeJS (express) + MongoDB 检索的结果 - 模拟 SQL 连接

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:24 24 4
gpt4 key购买 nike

有人可以告诉我以下情况的解决方案吗?

我有一个用 NodeJS Express 框架编写并使用 MongoDB 集合的日志应用程序。我设法从一个集合中获取结果,但我想迭代结果,根据第一个查询中的引用 ID 查询另一个集合,并向初始结果附加更多值,然后将响应发送到客户端。

我将粘贴我现在编码的内容,但我无法让它工作。我要么做错了,要么我想要的逻辑不正确。

请帮助我了解更多理论和事实,即我无法在异步 JS 函数之外使用结果。

提前致谢!

代码:

exports.findLogs = function(req, res) {
var params = req.body;
var query = req.query;
var coll = params.section;
if (coll === undefined) {
coll = 'traces';
}

db.collection(coll, function(err, collection) {
collection.count(function(err, count) {
var criteria = {
'limit': limit,
'skip': skip,
'sort': [[options.sortname, options.sortorder]]
}
collection.find({}, criteria).toArray(function(err, items) {
Object.keys(items).forEach(function(logIndex) {
var trace = items[logIndex];
var crit = {
'find': {LogId: trace.LogId},
'projection': {},
'limit': 1
}

// Get entry based on Criteria from `log` table
findOneBy(crit, 'log', function(err, log) {
if (log.length !== 1) {
// no reference found
} else {
// Appending here to log DOES NOT stick as expected
trace.ComputerName = log.ComputerName;
trace.ComputerIP = log.ComputerIP;
trace.LastSeen = log.LastSeen;
trace.TestVar = 'test1234';
}
});

// Appending here to trace works as expected
trace.Actions = 'MyAction';
});

results['total'] = count;
results['results'] = items.length;
results['rows'] = items;
res.send(results);
});
});
});
}

function findOneBy(criteria, coll, callback) {
var cFind = criteria.find;
var cProj = criteria.projection;
db.collection(coll, function(err, collection) {
if (err) return callback(err);
else return collection.find(cFind, cProj).toArray(callback);
});
}

最佳答案

您的函数 findOneBy 是异步的。当您的代码循环访问 items 中存储的结果数组时,每个结果都会触发异步查找。

但是,在所有这些返回之前,您将通过“res.send(results)”将结果发送到客户端。因此,当数据返回到 Node.JS 应用程序时,它是在结果发送之后的。

有几种方法可以处理这个问题,但我建议您考虑更像这样的逻辑(伪代码,因为我没有数据库镜像您的数据):

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);
});
});

});

您还可以考虑使用 Node.JS 的异步库之一,但它不会显着改变您需要执行的操作。

关于node.js - 将更多属性附加到从 NodeJS (express) + MongoDB 检索的结果 - 模拟 SQL 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18681256/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com