最近在用mongoDB搭建可视化系统的数据库,记录一下使用过程中解决的问题

目录结构:

  • 1.将csv文件导入到mongoDB
  • 2.使用mongoose建Model时,集合名称自动加s变复数的问题
  • 3.mongoDB数据库中将时间从字符串格式转换成Date日期格式
  • 4.循环集合更新文档中的某些字段**
  • 5.node.js+mongoDB教程**

1.将csv文件导入到mongoDB

手头的原始数据是csv格式的,要用mongoDB数据库首先遇到的问题就是这样导入数据,使用mongoimport命令即可,具体命令如下:

mongoimport -d users -c contacts –type csv –file path/of/file/to/import.csv

其中:
-d: 即–db的缩写,将csv文件导入的数据库
-c: 即–collection的缩写,csv在数据库中保存的集合名称

更多可选参数信息见官方文档

  • 如果csv文件第一行是字段名称,则使用–headerline

mongoimport -d users -c contacts –file /path/of/file/to/import.csv –headerline

  • 如果csv文件没有字段名称,则使用–fieldFile另行指定字段名称所在文件,字段名文件中,每行写入一个字段,不需要用逗号分隔,字段文件的格式可以为csv, txt等。

mongoimport -d users -c contacts –file /path/of/file/to/import.csv –fieldFile /path/of/fieldfile.csv

【!】这里我遇到一个问题,在怎么运行以上命令都报错,SyntaxError: missing ; before statement。这时只要退出shell即可,以上命令是在mongoDB安装目录下运行的,而不是shell中。

导入json,tsv格式的文件也是类似的操作,详见官方文档

2.使用mongoose建Model时,集合名称自动加s变复数的问题

【问题描述】

在使用mongoose连接mongoDB数据库的过程中,先建Schema,再建Model,分别如下:

1
2
3
4
5
6
7
8
9
10
...
//建Schema
var MovieSchema = new mongoose.Schema({
name: String,
password: String
});
...
//建Model
var Movie = mongoose.model('Movie', MovieSchema);
...

这样写本以为会添加到数据库Movie集合中,实际操作时会在数据库中新建集合movies,并完成添加操作。

如果建Model时,如下这样写,则会正常添加到movies集合中(没有movies,则创建并添加)。

1
var Movie = mongoose.model('movies', MovieSchema);

【原因分析】

由以上现象可以推断mongoose在内部创建collection时将我们传递的collection名小写化,同时如果小写化的名称后面没有字母s,则会在其后面添加s,因此出现创建集合movies。

【解决办法】

只要在创建Schema和Model的时候稍加改动,就可以免去小写化和自动+s的困扰,创建方法如下:

1
2
3
4
5
var MovieSchema = new mongoose.Schema({
name: String,
password: String
},{collection:'movie'});
var card = mongoose.model('movie', MovieSchema , 'movie');

3.mongoDB数据库中将时间从字符串格式转换成Date日期格式

在数据库中,有同是String类型的日期字段和时间字段,如下图,现在想把它们组装成一个Date类型的字段。

最开始的时候我是这样写的

1
var newDate = new Date("2015-04-01 19:20:33");

但是一直提示Invalid Date,百思不得解,直到我在Stack Overflow上看到这个问题Converting string to date in mongodb,原来是字符串拼接的问题。

下面是可以正常完成转换的格式中的一种

1
var newDate = new Date("2015 04 01 19:20:33 +0800");

格式可以正常转换了,但是有遇到另外一个问题,转换前后的数据是下图这样的


转换后的时间刚好少了8小时,而UTC(世界标准时间)刚好比CST(中国标准时间)晚8小时,即Robomongo的默认显示是时间标准时间,可以在设置中调整为所在地时区,调整方法如下图

调整后的时间显示,如下图

4.循环集合更新文档中的某些字段

转换一个doc的时间问题解决了,那么怎么更新正个集合的时间呢,最开始我的想法是这样的

1
2
3
4
db.collectionName.find({}).forEach(function (doc) {
doc.dateTime = new Date("dateJoinTIme");
print( doc.dateTime );
});

但是shell报错

TypeError: db.getCollection(…).find(…).foreach is not a function

【解决办法】使用 “Bulk”

具体的使用方法如下,这里用到了我在3中提到的转换时间的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var collection = db.getCollection('test');
var bulkOp = collection.initializeOrderedBulkOp();
var count = 0;
collection.find().forEach(function(doc) {
//重新组装new Date()中的时间字符串
    var dd = doc.date.split('-');
    var newDate = new Date(dd[0]+' '+dd[1]+' '+dd[2]+' '+':'+doc.time+' +0800');

//更新dateTime字段,没有此字段则添加字段
    bulkOp.find({ '_id': doc._id }).updateOne({
        '$set': { 'dateTime': newDate }
    });

//删除文档中的某个字段
bulkOp.find({ '_id': doc._id }).updateOne({
       '$unset': { 'time': doc.time }
   });

    count++;
    if (count % 100 === 0) {
        // 每100次操作后执行一次,并完成bulkOp的初始化
        bulkOp.execute();
        bulkOp = collection.initializeOrderedBulkOp();
    }
});
// 清理队列
if (count > 0) {
    bulkOp.execute();
}

5.node.js+mongoDB教程

在不断的遇到问题解决问题的过程中,查了一些书,不得不感慨技术更新换代太快,技术前进的速度远远超过了书的翻译速度,网上教程帮的很大忙,下面列举的这些教程不能说是完美无缺,但是在我搭建数据库和后台系统的过程中给了我很大的帮助,思路清晰明了,帮助我在极短的时间内快速上手。

mongoDB: 8篇mongoDB教程

express+mongoose: 目前14篇,还在更的一套比较完整的教程

node.js+mongoose: 一套简单的实现增删改查的样例


【参考资料】
mongoimport
CNode社区
4循环更新集合中的文档-Stack Overflow