2-MongoDB 创建文档

2020-09-04  本文已影响0人  前端程序猿

一、创建数据库

使用 use databaseName 命令切换数据库,如果数据库不存在则创建

> use test
switched to db test

使用 show collections 命令查看数据库下的所有集合,新建的数据库的集合为 0 个

> show collections

二、db.collection.insertOne()创建当个文档

The insertOne() method has the following syntax:

db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)
参数 类型 描述
document document 要插入到集合中的文档
writeConcern document (可选的) 表示一个文档的安全写级别
如果在事务中运行,请不要设置该参数
(以后文章会讲到)

department 这个集合插入第一条文档(department集合不存在时,会自动创建,并插入数据)

db.department.insertOne({
  _id: "employee1",
  name: "zhangsan",
  age: 18,
});

运行结果:

{ "acknowledged" : true, "insertedId" : "employee1" }

返回:一个文档描述

三、db.collection.insertOne 操作失败的情况

文档主键必须唯一,重复创建相同 _id 的文档时,将创建失败

try {
  db.department.insertOne({
    _id: "employee1",
    name: "lisi",
    age: 19,
  });
} catch (e) {
  print(e);
}

运行结果:

WriteError({
    "index" : 0,
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }",
    "op" : {
        "_id" : "employee1",
        "name" : "lisi",
        "age" : 19
    }
})

四、自动生成文档主键

人为的指定文档主键,并不安全,如果不指定 _id的值,MongoDB 会自动调用ObjectId() 生成文档主键,并确保唯一性

> ObjectId()
ObjectId("5f4fe0abb3dbdc66cacb3b8e")

不指定 _id 进行创建

db.department.insertOne({
  name: "lisi",
  age: 19,
});

运行结果:

{
    "acknowledged" : true,
    "insertedId" : ObjectId("5f4fe031b3dbdc66cacb3b8d")
}

五、db.collection.insertMany()创建多个文档

The insertMany() method has the following syntax:

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)
参数 类型 描述
document document 要插入到集合中的文档数组
writeConcern document (可选的) 表示一个文档的安全写级别
如果在事务中运行,请不要设置该参数
(以后文章会讲到)
ordered boolean (可选的) 一个布尔值,指定mongod实例应该执行有序插入还是无序插入。默认值为true
如果为false,则执行无序插入,如果其中一个文档发生错误,则继续处理数组中的其余文档。

一次性创建两个文档

db.department.insertMany([
  {
    name: "joe",
    age: 18,
  },
  {
    name: "lily",
    age: 17,
  },
]);

运行结果:

{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5f4fe3cdb3dbdc66cacb3b8f"),
        ObjectId("5f4fe3cdb3dbdc66cacb3b90")
    ]
}

返回:一个文档描述

六、db.collection.insertMany 操作失败的情况

文档主键必须唯一,重复创建相同 _id 的文档时,将创建失败

try {
  db.department.insertMany([
    {
      _id: "employee1",
      name: "mike",
      age: 19,
    },
    {
      name: "lucy",
      age: 17,
    },
  ]);
} catch (e) {
  print(e);
}

运行结果:

BulkWriteError({
    "writeErrors" : [
        {
            "index" : 0,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }",
            "op" : {
                "_id" : "employee1",
                "name" : "mike",
                "age" : 19
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 0,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

以上报错信息中发现 nInserted 值为 0, 即两条数据均没有创建成功

当我们配置 orderedfalse 时, 结果将会有所不同

try {
  db.department.insertMany(
    [
      {
        _id: "employee1",
        name: "mike",
        age: 19,
      },
      {
        name: "lucy",
        age: 17,
      },
    ],
    {
      ordered: false,
    }
  );
} catch (e) {
  print(e);
}

运行结果:

BulkWriteError({
    "writeErrors" : [
        {
            "index" : 0,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }",
            "op" : {
                "_id" : "employee1",
                "name" : "mike",
                "age" : 19
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 1,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

上面的结果可以发现 nInserted 的值为 1, 即有一条数据创建成功,_idemployee1 的文档,因为主键重复创建失败,另一条文档因为没有错误,所以成功被创建

七、db.collection.insert() 创建一个或多个文档

The insert() method has the following syntax:

db.collection.insert(
   <document or array of documents>,
   {
     writeConcern: <document>,
     ordered: <boolean>
   }
)
参数 类型 描述
document document 要插入到集合中的文档数组
writeConcern document (可选的) 表示一个文档的安全写级别
如果在事务中运行,请不要设置该参数
(以后文章会讲到)
ordered boolean (可选的) 一个布尔值,指定mongod实例应该执行有序插入还是无序插入。默认值为true
如果为false,则执行无序插入,如果其中一个文档发生错误,则继续处理数组中的其余文档。

创建一个文档

db.department.insert({
  name: "jake",
  age: 19,
});

运行结果:

WriteResult({ "nInserted" : 1 })

创建一个文档返回 WriteResult 对象

创建多个文档

db.department.insert([
  {
    name: "王五",
    age: 19,
  },
  {
    name: "李二狗",
    age: 17,
  },
]);

运行结果:

BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

创建多个文档返回 BulkWriteResult 对象

八、db.collection.insert() 操作失败的情况

创建一个文档失败的情况

db.department.insert({
  _id: "employee1",
  name: "李二蛋",
  age: 30,
});

运行结果:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }"
    }
})

返回 WriteResult 对象, 和创建成功返回同样类型的错误对象

创建多个文档失败的情况

db.department.insert([
  {
    _id: "employee1",
    name: "李四娣",
    age: 16,
  },
  {
    name: "李逍遥",
    age: 33,
  },
]);

运行结果:

BulkWriteResult({
    "writeErrors" : [
        {
            "index" : 0,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }",
            "op" : {
                "_id" : "employee1",
                "name" : "李四娣",
                "age" : 16
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 0,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

返回 BulkWriteResult 对象, 和创建成功返回同样类型的错误对象

当设置 ordered 参数为 false 时,则执行无序插入,如果其中一个文档发生错误,则继续处理数组中的其余文档

db.department.insert(
  [
    {
      _id: "employee1",
      name: "李四娣",
      age: 16,
    },
    {
      name: "李逍遥",
      age: 33,
    },
  ],
  {
    ordered: false,
  }
);

运行结果:

BulkWriteResult({
    "writeErrors" : [
        {
            "index" : 0,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: \"employee1\" }",
            "op" : {
                "_id" : "employee1",
                "name" : "李四娣",
                "age" : 16
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 1,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

返回结果发现,有一个报错,nInserted1 则表示成功创建了 1 个文档

九、db.collection.save() 保存文档

The save() method uses either the insert or the update command.

save()方法, 当保存新文档时,会调用 insert() 方法创建文档,当保存的文档 _id 已存在,会调用 update() 方法更新文档

提示: MongoDB 不推荐 db.collection.save() 方法。而是使用db.collection.insertOne()db.collection.replaceOne()

update()db.collection.replaceOne() 更新文档操作,后面的文章会讲解

The save() method has the following form:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

使用 save() 方法创建一个文档

db.department.save({
  name: "郑屠户",
  age: 55,
});

运行结果:

WriteResult({ "nInserted" : 1 })

使用 save() 方法创建多个文档

db.department.save([
  {
    name: "楚霸王",
    age: 37,
  },
  {
    name: "李寻欢",
    age: 33,
  },
]);

运行结果:

BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

可以发现,运行结果与 insert() 通用

十、ObjectId() 文档主键

ObjectId(<hexadecimal>)
参数 类型 描述
hexadecimal String (可选的)十二位的十六进制字符串值

十二位的十六进制表示为:

方法和属性:

Attribute/Method 描述
str 返回对象的十六进制字符串表示形式。
ObjectId.getTimestamp() 将对象的时间戳部分作为日期返回。
ObjectId.toString() 以字符串文本" ObjectId(…)"的形式返回 JavaScript 表示形式。
ObjectId.valueOf() 返回以十六进制字符串形式表示的对象。返回的字符串是 str 属性

创建一个 ObjectId

> const objId = ObjectId()
> objId
ObjectId("5f5084376310a4635f151165")

传入十六进制字符串创建 ObjectId

> ObjectId(objId.str)
ObjectId("5f5084376310a4635f151165")

属性和方法:

> objId.str
5f5084376310a4635f151165
> objId.toString()
ObjectId("5f5084376310a4635f151165")
> objId.valueOf()
5f5084376310a4635f151165
> objId.getTimestamp()
ISODate("2020-09-03T05:50:47Z")

十一、 复合主键

文档主键的值为另一个文档

db.department.insert({
  _id: { status: "leaving", gender: "male" },
  name: "白小飞",
  age: 35,
});

运行结果:

WriteResult({ "nInserted" : 1 })
>

复合主键也要满足唯一性

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: test.department index: _id_ dup key: { _id: { status: \"leaving\", gender: \"male\" } }"
    }
})
>

不过,当复合主键文档的键值对顺序改变时,MongoDB 会认为是不同的文档主键

db.department.insert({
  _id: { gender: "male", status: "leaving" },
  name: "杨贵妃",
  age: 18,
});

运行结果:

WriteResult({ "nInserted" : 1 })

十二、总结

上一篇下一篇

猜你喜欢

热点阅读