在说MongoDB数据插入操作之前,我们先来简单了解下它的数据逻辑结构.MongoDB的逻辑结构是一种层次结构。主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。文档(document)由键/值对构成,像{a:1};{s:"abc"}等,它是MongoDB核心单元.MongoDB的文档(document),相当于关系数据库中的一行记录。多个文档组成一个集合(collection),相当于关系数据库的表。多个集合(collection),逻辑上组织在一起,就是数据库(database)。一个MongoDB实例支持多个数据库(database)。下面我们步入正题:MongoDB数据插入操作.插入函数应该是insert函数,可是我发现很多人都在用save,甚至比insert用得更勤,不知道是因单词拼字难易还是其他什么.总之,我们先来看看怎么操作吧
首先,我们进入test数据库,其中创建了个user集合,我们打算往这个集合里面插入文档.
> db
test
> show collections
system.indexes
system.users
user
插入函数可以直接接收文档做为它的参数,也可以先把文档赋值给变量,再接收变量做为自己的参数,下面是只接以文档做为参数来插入数据:
> db.user.insert({fname:"jeff",lname:"jiang"})
> db.user.find()   #find函数相当于SQL里面的select,查询数据的功能.可以看到,之前的操作已经把数据插入进去了
{ "_id" : ObjectId("502cbc35e81129d4cd4dcf2f"), "fname" : "jeff", "lname" : "jiang" }
> db.user.save({fname:"xiaoqiang",lname:"he"})
> db.user.find()    #之前的操作已经把数据插入进去了
{ "_id" : ObjectId("502cbc35e81129d4cd4dcf2f"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("502cbdbfe81129d4cd4dcf30"), "fname" : "xiaoqiang", "lname" : "he" }
接着,是把文档赋值给变量,再接收变量做为自己的参数来进行插入操作,这种方法在要对同一个文档进行多次操作时会很有用:
> i={fname:"chengcheng",lname:"zhang"}
{ "fname" : "chengcheng", "lname" : "zhang" }
> j={fname:"dengdeng",lname:"pan"}
{ "fname" : "dengdeng", "lname" : "pan" }
> db.user.insert(i)
> db.user.save(j)
> db.user.find()     #之前的操作已经把数据插入进去了
{ "_id" : ObjectId("502cbc35e81129d4cd4dcf2f"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("502cbdbfe81129d4cd4dcf30"), "fname" : "xiaoqiang", "lname" : "he" }
{ "_id" : ObjectId("502cbe72e81129d4cd4dcf31"), "fname" : "chengcheng", "lname" : "zhang" }
{ "_id" : ObjectId("502cbe75e81129d4cd4dcf32"), "fname" : "dengdeng", "lname" : "pan" }
说了这么多,基本插入操作也基本会了.但insert和save函数到底有什么区别呢.不急,在SQL中,我们想到可以用
INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} (...),(...),...来进行一次插入多条记录.那么,在MongoDB中,我们是否也可以用insert或save函数来进行一次插入多条记录呢?我们先来试试看看:
> db.user.insert({ "fname" : "dengdeng", "lname" : "pan" },{ "fname" : "chengcheng", "lname" : "zhang" })
> db.user.find()
{ "_id" : ObjectId("505275657916a431166639b4"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("505275b47916a431166639b5"), "fname" : "xiaoqiang", "lname" : "he" }
{ "_id" : ObjectId("505276897916a431166639b6"), "fname" : "cheng", "lname" : "zhang" }
{ "_id" : ObjectId("505276907916a431166639b7"), "fname" : "dengdeng", "lname" : "pan" }
{ "_id" : ObjectId("50529cf17916a431166639bd"), "fname" : "dengdeng", "lname" : "pan" }
查看结果显示,数据插是插入进去了,但不是我们想象中那样,它默认把第二个参数"忽略"了.下面再看看save函数的插入情况:
> db.user.save({ "fname" : "dengdeng", "lname" : "pan" },{ "fname" : "chengcheng", "lname" : "zhang" })
> db.user.find()
{ "_id" : ObjectId("505275657916a431166639b4"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("505275b47916a431166639b5"), "fname" : "xiaoqiang", "lname" : "he" }
{ "_id" : ObjectId("505276897916a431166639b6"), "fname" : "cheng", "lname" : "zhang" }
{ "_id" : ObjectId("505276907916a431166639b7"), "fname" : "dengdeng", "lname" : "pan" }
{ "_id" : ObjectId("50529cf17916a431166639bd"), "fname" : "dengdeng", "lname" : "pan" }
{ "_id" : ObjectId("50529d207916a431166639be"), "fname" : "dengdeng", "lname" : "pan" }
结果也不是同时插入了两条记录,它也默认把第二个参数"忽略"了.那么,我们试试它们是不是真的把第二个参数忽略了呢,下面试试以变量当参数插入数据看看什么情况:
> i={fname:"chengcheng",lname:"zhang"}
{ "fname" : "chengcheng", "lname" : "zhang" }
> j={fname:"dengdeng",lname:"pan"}
{ "fname" : "dengdeng", "lname" : "pan" }
> db.user.insert(i,j)
> db.user.find()
{ "_id" : ObjectId("505275657916a431166639b4"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("505275b47916a431166639b5"), "fname" : "xiaoqiang", "lname" : "he" }
{ "_id" : ObjectId("505276897916a431166639b6"), "fname" : "cheng", "lname" : "zhang" }
{ "_id" : ObjectId("505276907916a431166639b7"), "fname" : "dengdeng", "lname" : "pan" }
{ "_id" : ObjectId("50529bfd7916a431166639bb"), "fname" : "chengcheng", "lname" : "zhang" }
> i
{ "fname" : "chengcheng", "lname" : "zhang" }
> j
{ "fname" : "dengdeng", "lname" : "pan" }
> db.user.save(i,j)
> db.user.find()
{ "_id" : ObjectId("505275657916a431166639b4"), "fname" : "jeff", "lname" : "jiang" }
{ "_id" : ObjectId("505275b47916a431166639b5"), "fname" : "xiaoqiang", "lname" : "he" }
{ "_id" : ObjectId("505276897916a431166639b6"), "fname" : "cheng", "lname" : "zhang" }
{ "_id" : ObjectId("505276907916a431166639b7"), "fname" : "dengdeng", "lname" : "pan" }
{ "_id" : ObjectId("50529bfd7916a431166639bb"), "fname" : "chengcheng", "lname" : "zhang" }
{ "_id" : ObjectId("50529c1d7916a431166639bc"), "fname" : "chengcheng", "lname" : "zhang" }
> i
{
 "fname" : "chengcheng",
 "lname" : "zhang",
 "_id" : ObjectId("50529c1d7916a431166639bc")
}
> j
{ "fname" : "dengdeng", "lname" : "pan" }
看到没有,数据还是和之前一样的情况插入集合了,所以想像insert语句那样一起插入多条数据好像不太可能,不过我们可以使用循环或者批量插入数据工具(mongoimport).这里我们先不说批量插入.注意,insert和save的区别来了.insert函数不会改变变量值,而save函数把第一个变量的值改变了.为什么会这样呢,来看看它们的函数代码.MongDB有个很方便的地方,只打函数的名字而不加括号,就能查看该函数的功能用法.
> db.user.insert
function (obj, _allow_dot) {
    if (!obj) {
        throw "no object passed to insert!";
    }
    if (!_allow_dot) {
        this._validateForStorage(obj);
    }
    if (typeof obj._id == "undefined" && !Array.isArray(obj)) {
        var tmp = obj;
        obj = {_id:new ObjectId};
        for (var key in tmp) {
            obj[key] = tmp[key];
        }
    }
    this._db._initExtraInfo();
    this._mongo.insert(this._fullName, obj);
    this._lastID = obj._id;
    this._db._getExtraInfo("Inserted");
}
> db.user.save
function (obj) {
    if (obj == null || typeof obj == "undefined") {
        throw "can't save a null";
    }
    if (typeof obj == "number" || typeof obj == "string") {
        throw "can't save a number or string";
    }
    if (typeof obj._id == "undefined") {
        obj._id = new ObjectId;
        return this.insert(obj);
    } else {
        return this.update({_id:obj._id}, obj, true);
    }
}
由上面可以看出,save函数实际就是根据参数条件,调用了insert或update函数.如果想插入的数据对象存在,insert函数会报错,而save函数是改变原来的对象;如果想插入的对象不存在,那么它们执行相同的插入操作.这里可以用几个字来概括它们两的区别,即所谓"有则改之,无则加之".