javascript - 如何从 MongoDB 中的嵌套 find() 将对象数组设置回迭代集合?

标签 javascript angularjs node.js mongodb

我使用 AngularJS、NodeJS 和 MongoDB 开发应用程序。我想加载按 ProductCategoryCode 发送的产品分类 AngualrJS 到 NodeJS。首先,我需要按 ProductCategoryCode 查找产品,然后迭代每个产品以按 UomCode 和 ContainUomCode 查找 Uoms 每个产品应该有 2 uoms。如何将 uom 对象 docUom 设置回产品文档 doc[i] 并更新到产品集合 doc

对于以下代码行

doc[i].Uom = docUom;

系统抛出错误无法设置未定义的属性“Uom”。

这是product.js片段代码。

router.get("/LoadProductByProductCategoryCode/:productCategoryCode", function (req, res) {
    console.log('user.js -> /users ');
    var productCategoryCode = req.params.productCategoryCode;
    console.log(productCategoryCode );
    var MongoClient = require('mongodb').MongoClient,
        format = require('util').format;

    MongoClient.connect('mongodb://localhost:27017/NodeDB', function (err, db) {
            if (err) throw err;

            var query = { ProductCategoryCode : productCategoryCode}
            var new_product = [];
            findProduct(db, query, function (err, doc) {
                if(err) {
                    // something went wrong
                    console.log(err);
                    return;
                }
                if (doc) {
                    console.log("Found Product..."+doc.length);
                    for (var i = 0; i < doc.length; i++) {
                        console.log(doc[i].ProductCode + " each document " + doc[i].UomCode + " " + doc[i].ContainUomCode);
                        var qUom = { 
                            $or: [ { UomCode: doc[i].UomCode}, { UomCode: doc[i].ContainUomCode } ] 
                        }
                        // Find uom
                        findUom(db, qUom, function(errUom, docUom) {
                            if(errUom) {
                                console.log("error " + errUom);
                                return;
                            }
                            if (docUom) {
                                doc[i].Uom = docUom;
                                console.dir(product);
                            }
                        });
                    }
                    res.json(doc);
                } else {
                    console.log('something happen');
                }
            }); //End 
        }); // MongoClient
        var findProduct = function (db, query, callback) {
            db.collection('Product').find(query).toArray(function (err, doc) {
                if(err) {
                    callback(err);
                }
                else {
                    callback(null, doc);
                }
            });
        }
        var findUom = function(db, queryUom, callback) {
            db.collection('Uom').find(queryUom).toArray(function (err, doc) {
            //    db.close();
                if(err) {
                    callback(err);
                }
                else {
                    callback(null, doc);
                }
            });
        }
});

有什么想法吗?谢谢

最佳答案

由于 Node.js MongoDB 驱动程序的异步特性,findProduct()findUom() 方法都会启动,但在到达 res.json(doc) 时不一定完成,这意味着 doc 仍将为空。您期望它以线性方式工作,但 Node 的工作方式不同。

相反,您应该在所有异步调用完成后发回响应,这意味着您可以尝试以下操作:

findProduct(db, query, function (err, doc) {
    if(err) {
        // something went wrong
        console.log(err);
        return;
    }
    var processedProduct = function (item) {
        console.log(item.ProductCode + " each document " + item.UomCode + " " + item.ContainUomCode);
        var qUom = { 
            $or: [ { UomCode: item.UomCode}, { UomCode: item.ContainUomCode } ] 
        }
        // Find uom
        findUom(db, qUom, function(errUom, docUom) {
            if(errUom) {
                console.log("error " + errUom);
                return;
            }
            if (docUom) {
                item.Uom = docUom;
                console.dir(product);
                return item;
            }
        });        
    }        
    if (doc) {
        var productsToFind = doc.length;
        var products = [];
        console.log("Found Products..." + productsToFind);        
        for (var i = 0; i < doc.length; i++) {
            product = doc[i];
            product = processedProduct(product);
            products.push(product);
            productsToFind -= 1;
            if(productsToFind === 0){
                res.json(products);
            }            
        }        
    } else {
        console.log('something happen');
    }
}); //End 

我可以更好地解释异步调用和回调,因为这个主题有点宽泛,但从上面您可以了解到,我对所有内部异步调用使用了一个计数器 productsToFind ,一旦每个 findUom() 调用完成此计数器就会递减,一旦达到 0,就意味着所有回调都已触发。

关于javascript - 如何从 MongoDB 中的嵌套 find() 将对象数组设置回迭代集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29341648/

相关文章:

javascript - 在 Node.js/Angular 应用程序中查询来自不同主机的数据时,如何遵守访问控制源异常?

angularjs - 在angularjs xeditable表成功之前将数据插入表(数组)

node.js - Node js TCP 服务器,socket.on ('data' ) - 数据缓冲区包含高负载时的垃圾数据

java - 在 Struts 2 中使用 ModelDriven 访问 POJO 属性?

javascript - 在 JS (Wordpress) 中获取帖子数

javascript - AngularJS 和 UI-Select multiple with data

node.js - 密码发布无法在 Nodejs 服务器上使用 Reactjs

javascript - LABjs 有条件地加载脚本

html - 基于 3D 六 Angular 网格 CSS 未按需要显示

javascript - 如何在客户端浏览器中使用 Node 缓冲区模块 - 请详细说明