在Node JS中缓慢加载大型MongoDB数据库

时间:2016-09-23 09:18:24

标签: html node.js mongodb d3.js

我创建了一个包含Node JS,Express JS,Mongoose和D3 JS的网页。

在网页中,它包含3个下拉菜单:部门,员工,周。 网页的使用情况如下:

  1. 当'部门'被选中,'员工'菜单将被过滤,仅显示来自所选部门的菜单。这同样适用于周'周。在'员工'之后被选中。
  2. 选择3个菜单后,' PLOT'单击按钮,将绘制折线图(使用d3.js)以显示该月的员工工作时间。
  3. MongoDB Json

    { dep: '1',
      emp: 'Mr A',
      week: 1,
      hrs: [{
              {1,8},
              {2,10},
              ...
           }]
    }
    

    以下是我的代码片段:

    routes.js

    // Connect the required database and collection
    var dataAll = require('./models/dataModel'); 
    
    module.exports = function(app) {
    
    app.get('/api/data', function(req, res) {
        dataAll.find({}, {}, function(err, dataRes) {
            res.json(dataRes);
        });
    }
    
    app.get('*', function(req,res) {
        res.sendfile('./index.html');
    }
    }
    

    的index.html

    ... // More codes
    <div id="menuSelect1"></div>
    <div id="menuSelect2"></div>
    <div id="menuSelect3"></div>
    ...
    <script src="./display.js" type='text/javascript'></script>
    ... // More codes
    

    display.js

    //Menu (Department,Employee,Week) Information is gathered here
    
    queue()
    .defer(d3.json, "/api/data")
    .await(createPlot);
    
    function createPlot(error, plotData) {
    var myData = plotData;
    
    var depData = d3.nest()
            .key(function(d) {return d.dep;})
            .rollup(function(v) {return v.length;})
            .entries(myData);
    
    selectField1 = d3.select('#menuSelect1')
            .append("select")
            .on("change", menu1change)
            .selectAll(depData)
            .enter()
            .append("option")
            .attr("value", function(d) {return d.key;})
            .text(function(d) {return d.key;});
    
    function menu1Change() {
        //Filter Next Menu with the option chosen in this menu
        ... // More codes
        var selectedVal = this.options[this.selectedIndex].value;
        var empData = dataSet.filter(function(d) { return d.emp = selectString; });
        ... // More codes
    }   
    ... // More codes
    

    }

    问题: 从功能上讲,它按预期工作。问题是当数据库变得越来越大时,页面的加载变得非常慢(加载的时间)。我认为这应该是由于检索所有数据的路由(.find({},{}))但我认为我需要它,因为我在&#39; display.js&#39;中使用它。过滤我的菜单选项。

    有没有更好的方法来解决性能问题?

1 个答案:

答案 0 :(得分:0)

很少需要将所有数据发送到客户端。实际上,我还没有看到一个带有单个端点的API,它将整个数据库返回给每个人。

很难为您提供任何具体的解决方案,不知道您的数据是什么样的,它有多大,增长速度等等。性能问题可能与查询数据库,大数据传输,或浏览器解析的大型JSON。

在任何情况下,您都不应该无限制地将所有数据库发送到客户端。通常它实现时要跳过许多记录以及要返回的最大记录数。

像LoopBack这样的一些框架为你做了,请参阅:

如果你正在使用Express,那么你必须自己实施这些限制。

要测试瓶颈,您可以运行Mongo shell并尝试从那里运行.find({},{})查询以查看它需要多长时间。您可以在浏览器的开发者工具中查看传输大小和时间。这可能会让你缩小需要最多关注的地方,但无论它有多大,都要返回整个数据库,这已经是一个很好的起点。