MongoDB 连接和数据库/集合/文档操作

MongoDB 不同的连接方式

首先启动服务(bin 目录下执行 mongodb)

使用 MongoDB shell 连接服务器

标准URL连接语法

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
  • mongodb:固定格式,必须指定
  • username:password@:可选项,设置后在连接后会尝试登陆数据库
  • host1:必须置顶至少一个 host ;如果要连接复制集,需要指定多个地址
  • portX :可选的指定端口,默认是27017
  • /database :如果指定账号密码,连接验证登陆指定数据库;否则打开 test 数据库
  • ?options :连接选项,所有连接选项都是键值对 name=value,键值对之间通过“ & ”或 “ ;”隔开

连接选项 options:

选项 描述
replicaSet=name 验证replica set的名称。 Impliesconnect=replicaSet.
slaveOk=true|false true:在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。false: 在 connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet 模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。
safe=true|false true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS).false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。
w=n 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。
wtimeoutMS=ms 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
fsync=true|false true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true.false: 驱动不会添加到getLastError命令中。
journal=true|false 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
connectTimeoutMS=ms 可以打开连接的时间。
socketTimeoutMS=ms 发送和接受sockets的时间。

实例

使用默认端口连接服务

mongodb://localhost

通过 shell 连接服务

./mongo
# 使用账号密码连接到本地服务
mongodb://admin:123456@localhost/
# 使用账号密码连接登陆到指定数据库
mongodb://admin:123456@localhost/test

其他连接实例

mongodb://localhost
mongodb://fred:foobar@localhost
mongodb://fred:foobar@localhost/baz

# 连接 replica pair 服务器 1 为 example1.com,2 为 example2.com
mongodb://example1.com:27017,example2.com:27017
# 连接 replica set 三台服务器 (端口 27017, 27018, 和27019)
mongodb://localhost,localhost:27018,localhost:27019
# 连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
mongodb://host1,host2,host3/?slaveOk=true
# 直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
mongodb://host1,host2,host3/?connect=direct;slaveOk=true
# 安全模式连接到localhost:
mongodb://localhost/?safe=true
# 以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000

数据库操作

创建数据库

在 MongoDB 中,集合只有在内容插入后才会创建

就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

# 如果数据库不存在则创建,否则切换到这个数据库
use DATABASE_NAME
use newtest

# 查看当前数据库,新创建的数据库未在列表中显示
show dbs

# 插入数据后再次查询即可显示
db.newtest.insert({"name":"测试"})
show dbs

删除数据库

# 删除当前数据库,默认为 test
db.dropDatabase()

集合操作

创建集合

如果在不存在的集合中直接插入文档,则集合会自动被创建

# 语法
db.createCollection(name,options)

# 例子
# 指定大小为 6142800 字节,文档最大数量 10000,建立 _id 索引
db.createCollection("mycol",{capped:true,autoIndexId:true,size:6142800,max:10000})
  • name:要创建的集合名称
  • options:可选参数,制定有关内存大小及索引的选项

options 可选项

字段 类型 描述
capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。
autoIndexId 布尔 3.2 之后不再支持该参数。(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
size 数值 (可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。
max 数值 (可选)指定固定集合中包含文档的最大数量。

删除集合

# 语法
db.<集合>.drop()

# 查看是否删除
show collections

文档操作

插入文档

语法

使用 insert() 或 save() 方法向集合中插入文档,语法如下:

# 语法
db.<collection>.insert(<document>)
db.<collection>.save(<document>)
  • save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne()db.collection.replaceOne() 来代替。
  • insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
# 新版语法
# 单插
db.<collection>.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)
# 多插
db.<collection>.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)
  • document:要写入的文档。
  • writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
  • ordered:指定是否按顺序写入,默认 true,按顺序写入。

实例

# 向 col 集合插入一个文档
>db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})
# 查看
> db.col.find()
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
> 
---
# 先定义变量法
> document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});
# 插入变量
> db.col.insert(document)
WriteResult({ "nInserted" : 1 })

更新文档

语法

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

实例

# 插入数据
>db.col.insert({
    title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})
# 更新数据,更新标题
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 输出信息
# 查看
> db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一个 Nosql 数据库",
        "by" : "菜鸟教程",
        "url" : "http://www.runoob.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
>

删除文档

语法

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)
  • query :(可选)删除的文档的条件。
  • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
  • writeConcern :(可选)抛出异常的级别。

实例

# 删除符合条件的文档
>db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 })           # 删除了两条数据

# 删除全部
>db.col.remove({})

查询文档

语法

MongoDB 使用 find() 方法以非结构化的方式来显示文档

# 查询
db.collection.find(query, projection)
db.collection.findOne(query, projection)
# 如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
db.col.find().pretty()
db.col.findOne().pretty()
  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

条件语句

操作 格式 范例 RDBMS中的类似语句
等于 {<key>:<value>} db.col.find({"by":"菜鸟教程"}).pretty() where by = '菜鸟教程'
小于 {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小于或等于 {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大于 {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大于或等于 {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等于 {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50

and 条件

# 多个条件以逗号隔开
db.col.find({key1:value1, key2:value2}).pretty()
# 例如
db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()

or 条件

# 使用 $or 关键字
db.col.find({$or: [{key1: value1}, {key2:value2}]}).pretty()
# 例如
db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

组合使用实例

db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

条件操作符

  • (>) 大于 - $gt
  • (<) 小于 - $lt
  • (>=) 大于等于 - $gte
  • (<= ) 小于等于 - $lte
  • $type,指定查询的数据类型

指定数量:Limit() 和 Skip()

# limit 指定读取的条数
db.COLLECTION_NAME.find().limit(NUMBER)

# skip 跳过指定数量的数据
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

排序 sort()

# 指定排序的字段, 1 是升序排列,-1 是降序排列
db.COLLECTION_NAME.find().sort({KEY:1})

索引

索引可以极大的提高查询效率

索引是一种特殊的数据结构,存储在一个易于遍历读取的数据集合中,是对数据库表中一列或多列的值进行排序的一种结构

createIndex() 方法

# 创建 key 的索引
db.collection.createIndex(key,options)
# 例 1,给 title 字段升序创建索引
db.col.createIndex({"title":1})
# 例 2,按 title 字段升序,description 字段降序,创建索引
db.col.createIndex({"title":1,"description":-1})
# 例 3,使用 background 参数在后台建立索引
db.values.createIndex({open: 1, close: 1}, {background: true})
Parameter Type Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

其他索引方法

# 查看集合索引
db.col.getIndexes()

# 查看集合索引大小
db.col.totalIndexSize()

# 删除集合所有索引
db.col.dropIndexes()

# 删除集合指定索引
db.col.dropIndex("索引名称")

聚合方法

用于处理数据,如统计平均值,求和等操作,类似 SQL 语句中的 count(*)

aggregate() 方法

db.col.aggregate(AGGREGATE_OPERATION)
# 其中 AGGREGATE_OPERATION

# 例1 求和
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
# 类似于 SQL 的: select by_user, count(*) from mycol group by by_user

# 例1 格式处理后
db.mycol.aggregate(
	[
		{
			$group : {
				_id : "$by_user", num_tutorial : {$sum : 1}
			}
		}
	]
)

聚合表达式

表达式 描述 实例
$sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 将值加入一个数组中,不会判断是否有重复的值。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

管道

管道在 Unix 和 Linux 中用于将当前命令的输出结果作为下一个命令的参数

MongoDB 的聚合管道将文档在一个管道处理完毕后,将结果传递给下一个管道处理,管道操作是可以重复的

表达式:处理输入文档并输出。是无状态的,只能用于计算按当前聚合管道的文档,不能处理其他的文档

聚合框架的常用操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。
# 两个管道的例子
# 先处理 $match 管道,获取分数在70~90之间的记录,然后处理 $group 管道,计算和数
db.articles.aggregate( [
                        { $match : { score : { $gt : 70, $lte : 90 } } },
                        { $group: { _id: null, count: { $sum: 1 } } }
                       ] );
posted @ 2021-11-04 14:26  景北斗  阅读(882)  评论(0编辑  收藏  举报