从五一假期回来到今天5月20号,从node.js和mongoDB的小白,到现在基本完成了第一步的目标。截图留念。

这半个月来,就像坐着过山车,一直处于遇到问题的苦闷和解决问题的激动中,一个问题的结束就是另一个问题的开始。中间遇到问题找不到答案的时候,也曾怀疑过用一个自己完全不熟悉的数据库是不是太不明智,不过问题解决了,就又愉快的用起了mongoDB,谁让自己好奇呢。

下面整理我跨越的那些问题:

目录结构:

  • 1.mongoDB索引操作
  • 2.循环中的回调函数
  • 3.ejs里面输出json对象给js文件调用

1.mongoDB索引操作

其中一个功能需要大量查询,如果不做优化全表扫描,页面的等待时间很长。

先用两个查询做对比:

建索引前:
9.269s,这还是在工作站上跑出了的结果,自己的电脑就悲剧了。

建索引后:
0.003s,毫秒级查询速度快的飞起。

这里用到了mongoDB的索引,基本的索引操作整理如下:

  • 建立索引:
1
2
3
4
5
6
// 在name字段上升序(1)建立索引
db.collection.ensureIndex({"name":1});
// 在name字段上降序(-1)建立索引
db.collection.ensureIndex({"name":-1});
// 建立复合索引,先根据name升序,再根据age升序,适合查询中有多个查询条件的情况
db.collection.ensureIndex({"name":1,"age":1});
  • 查询索引
1
db.collection.getIndexes();
  • 删除索引
1
db.collection.dropIndex({"name":1});

2.循环中的回调函数

这是异步操作中常见的一个陷阱,for循环中的回调函数内,使用for的计数器i,像下面这样:

1
2
3
4
5
6
7
8
var arr = [1,2,3];
for (var i = 0, len = arr.length; i < len; i++) {
...
model.count(query, function(err, data) {
console.log(i);
console.log(arr[i]);
});
}

结果如下:

3
undefined
3
undefined
3
undefined

即i一直输出len的值,也就是循环结束后的值,因此也导致arr[i]下标超出数组的大小,故一直输出undefined。

【解决办法】

  • 利用JavaScript函数编程特性,手动建立闭包
1
2
3
4
5
6
7
8
9
10
var arr = [1, 2, 3];
for (var i = 0, len = arr.length; i < len; i++) {
...
(function(i) {
model.count(query, function(err, data) {
console.log(i);
console.log(arr[i]);
});
})(i);
}

此方法虽然解决了回调函数内使用i的问题,但是多个model.count函数并行执行,并不能保证执行按照循环的顺序进行。

  • 数组的foreach循环
1
2
3
4
5
6
7
var arr = [1, 2, 3];
arr.foreach(function(num){
...
model.count(query, function(err, data) {
console.log(num);
});
});

更详细解释

3.ejs里面输出json对象给js文件调用

现在呢,终于顺利的从数据库查询到想要的数据,也顺利的传给了ejs页面,那么怎么继续向前传,传给js文件来展示这些数据呢?

首先我们看看传过来的数据,服务器端代码如下:

1
2
3
router.post('/', function(req, res, next) {
res.render('index',{info:{"a":1,"b":2}});
});

客户端js文件读取传递过来的信息,如下:

1
2
3
4
5
<script type="text/javascript">
var data = '<%- JSON.stringify(info) %>';
json = JSON.parse(data);
console.log(data["a"]);
</script>


【参考资料】
8天学通MongoDB
ejs里面怎么输出json对象给页面的js调用