mongodb基本操作

Posted 饿了吃小孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb基本操作相关的知识,希望对你有一定的参考价值。

mongodb基本操作

数据库和集合基本操作

数据库

  • 一个 MongoDB 可以创建多个数据库

  • 使用 show dbs 可以查看所有数据库的列表

  • 执行 db 命令则可以查看当前数据库对象或者集合

  • 运行 use 命令可以连接到指定的数据库

文档

文档是 MongoDB 的核心,类似于 SQLite 数据库(关系数据库)中的每一行数据。多个键及其关联的值放在一起就是文档。

假设两个文档

# user文档
{
  "name": "Tom Hanks",
  "contact": "987654321",
  "dob": "01-01-1991"
}
?
# address文档
{
  "building": "22 A, Indiana Apt",
  "pincode": 123456,
  "city": "chengdu",
  "state": "sichuan"
}

嵌入式关系

# 这就是嵌入式的关系
{
  "name": "Tom Hanks",
  "contact": "987654321",
  "dob": "01-01-1991",
  "address":
  [{
  "building": "22 A, Indiana Apt",
  "pincode": 123456,
  "city": "chengdu",
  "state": "sichuan"
  },
  {
  "building": "170 A, Acropolis Apt",
  "pincode": 456789,
  "city": "beijing",
  "state": "beijing"
  }]
}

引用式关系

# 这就是引用式关系
{
  "name": "Tom Benzamin",
  "contact": "987654321",
  "dob": "01-01-1991",
  "address_ids": [
     ObjectId("52ffc4a5d85242602e000000")    #对应address文档的id字段
  ]
}

在实际应用的时候,嵌入式关系比较适合一对一的关系,引用式关系比较适合一对多或者多对多的情况。

集合

集合就是一组文档的组合,就相当于是关系数据库中的表,在 MongoDB 中可以存储不同的文档结构的文档。

元数据

数据库的信息存储在集合中,他们统一使用系统的命名空间:DBNAME.system.*

DBNAME 可用 db 或数据库名替代:

  • DBNAME.system.namespaces :列出所有名字空间

  • DBNAME.system.indexs :列出所有索引

  • DBNAME.system.profile :列出数据库概要信息

  • DBNAME.system.users :列出访问数据库的用户

  • DBNAME.system.sources :列出服务器信息

数据库创建和销毁

创建数据库

启动服务后,进入 MongoDB 命令行操作界面:

mongo

使用 use 命令创建数据库:

use mydb

查看当前连接的数据库:

db

查看所有的数据库:

show dbs

销毁数据库

使用 db.dropDatabase() 销毁数据库:

> use local
switched to db local
> db.dropDatabase()

集合的创建和删除

创建集合

在数据库 mydb 中创建一个集合

> use mydb
switched to db mydb
> db.createCollection("users")

查看创建的集合:

> show collections

删除集合

删除集合的方法如下:(删除 users 集合)

> show collections
> db.users.drop()

向集合中插入数据

插入数据时,如果 users 集合没有创建会自动创建。

> use mydb
switched to db mydb
> db.users.insert([
... { name : "jam",
... email : "jam@qq.com"
... },
... { name : "tom",
... email : "tom@qq.com"
... }
... ])

使用 save()

插入数据时,如果 users 集合没有创建会自动创建。

> use mydb2
switched to db mydb2
> db.users.save([
... { name : "jam",
... email : "jam@qq.com"
... },
... { name : "tom",
... email : "tom@qq.com"
... }
... ])

insert 和 save 的区别:为了方便记忆,可以先从字面上进行理解,insert 是插入,侧重于新增一个记录的含义;save 是保存,可以保存一个新的记录,也可以保存对一个记录的修改。因此,insert 不能插入一条已经存在的记录,如果已经有了一条记录(以主键为准),insert 操作会报错,而使用 save 指令则会更新原记录。

查询语句

find查询

查询数据,不加任何参数默认返回所有数据记录:

> db.post.find()

这条语句会返回 post 集合中的所有文档,实际应用中不常见,因为这样会导致大量的数据传输,造成服务器响应迟缓甚至失去响应。

pretty语句

pretty() 可以使查询输出的结果更美观。

> db.post.find().pretty()

mongodb中的and

MongoDB 不需要类似于其他数据库的 AND 运算符,当 find() 中传入多个键值对时,MongoDB 就会将其作为 AND 查询处理。

用法:db.mycol.find({ key1: value1, key2: value2 }).pretty()

> db.post.find({"by":"shiyanlou","to": "chenshi"}).pretty(

mongodb中的or

MongoDB 中,OR 查询语句以 $or 作为关键词,用法如下:

> db.post.find(
  {
    $or: [
      {key1: value1}, {key2:value2}
    ]
  }
).pretty()

操作示例:

> db.post.find({
    $or:[
        {"by":"shiyanlou"},
        {"title": "MongoDB Overview"}
    ]
}).pretty()

同时使用and和or

> db.post.find({
    "likes": {$gt:10},
    $or: [
        {"by": "shiyanlou"},
        {"title": "MongoDB Overview"}
    ]
}).pretty()
db.createCollection("shiyanlou2", { capped : 1, autoIndexId : 1, size : 6142800, max : 10000 } ) #带参数
{ "ok ": 1 }

参数描述:

  • capped:类型为 Boolean,如果为 true 则创建一个固定大小的集合,当其条目达到最大时可以自动覆盖以前的条目。在设置其为 true 时也要指定参数大小;

  • autoIndexId:类型为 Boolean,默认为 false,如果设置为 true,则会在 _id 字段上自动创建索引;

  • size:如果 capped 为 true 则需要指定,指定参数的最大值,单位为 byte;

  • max:指定最大的文档数。

删除集合

db.shiyanlou.drop()

插入文档

?
> userdoc1=({"user_id":1,"name":"cloud","state":"active","actor":"user","e-mail":"test@qq.com","VM_num":2,"time":[{"date":"2014-08-12","hour":"10:53 PM"}] })
> userdoc2=({"user_id":2,"name":"testadmin","state":"active","actor":"admin","e-mail":"test@qq.com","VM_num":2,"time":[{"date":"2014-08-11","hour":"06:34 AM"}] })
> doc1=({"name":"peter","position":"teacher"})    #先定义文档
?
> use Chenshi
switched to db Chenshi
> db.shiyanlou.insert(userdoc1)
WriteResult({"nInserted":1})
> db.shiyanlou.insert(userdoc2)
WriteResult({"nInserted":1})
> db.shiyanlou.insert(doc1)
WriteResult({"nInserted":1})

更新文档

> db.shiyanlou.update({"user_id":2,"e-mail":"test@qq.com"},{$set:{"e-mail":"group@qq.com"}})
WriteResult({"nMatched":1,"nUpserted":1,"nModified":1})
> db.shiyanlou.find()
  • 将 user_id=2 的文档的 e-mail 改为 group@qq.com

  • 第一个大括号内容标示查找条件,第二个大括号内容则表示更新后的数据

  • 默认的 update 函数只对一个文档更新,如果想作用所有文档,则需要加入 multi:true

操作实例:

db.shiyanlou.update({"e-mail":"test@qq.com"},{$set:{"e-mail":"group@qq.com"}},{multi:true})

替换已经存在的文档

db.shiyanlou.save({"_id":ObjectId("53ea174ccb4c62646d9544f4"),"name":"Bob","position":"techer"})

WriteResult({"nMatched":1,"nUpserted":1,"nModified":1})

这里的 _id 对应的是要替换文档的 _id。

跟 insert 差不多,但是 save 更好用。

删除文档

db.shiyanlou.save({"_id":ObjectId("53ea174ccb4c62646d9544f4"),"name":"Bob","position":"techer"})
WriteResult({"nMatched":1,"nUpserted":1,"nModified":1})

这里的 _id 对应的是要替换文档的 _id。

跟 insert 差不多,但是 save 更好用。

语句总结

createCollection():创建集合
db.COLLECTION.drop():删除集合
db.COLLECTION_NAME.insert(document):插入文档
db.COLLECTION_NAME.update(SELECTION_CRITERIA,UPDATED_DATA):更新文档
db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA}):替换已存在的文档
db.COLLECTION_NAME.remove(DELECTION_CRITERIA):删除文档

查询、索引与聚合

> use Chenshi
switched to db Chenshi
?
> db.createCollection("shiyanlou")    #无参数
{"ok":1}
?
userdoc1=({"user_id":1,"name":"cloud","state":"active","actor":"user","e-mail":"test@qq.com","VM_num":2,"time":[{"date":"2014-08-12","hour":"10:53 PM"}] })
?
> userdoc2=({"user_id":2,"name":"testadmin","state":"active","actor":"admin","e-mail":"test@qq.com","VM_num":2,"time":[{"date":"2014-08-11","hour":"06:34 AM"}] })
?
> doc=({"name":"peter","position":"teacher"})
?
db.shiyanlou.insert(userdoc1)
WriteResult({"nInserted":1})
> db.shiyanlou.insert(userdoc2)
WriteResult({"nInserted":1})
> db.shiyanlou.insert(doc)
WriteResult({"nInserted":1})

查询语句find()

db.shiyanlou.find({user_id:{$gt:1}})
db.shiyanlou.find({user_id:{$lte:2,$gt:1}})

条件操作符type

可选的key值如下

$type:[key]:

1: 双精度型(Double)
2: 字符串(String)
3: 对象(Object)
4: 数组(Array)
5: 二进制数据(Binary data)
7: 对象 ID(Object id)
8: 布尔类型(Boolean)
9: 日期(Date)
10: 空(Null)
11: 正则表达式(Regular Expression)
13: JS 代码(javascript)
14: 符号(Symbol)
15: 有作用域的 JS 代码(JavaScript with scope)
16: 32 位整型数(32-bit integer)
17: 时间戳(Timestamp)
18: 64 位整型数(64-bit integer)
-1: 最小值(Min key)
127: 最大值(Max key)

 

db.shiyanlou.find({"name":{$type:2}})

上面的命令是用于查找 name 是字符串的文档记录,它等同于下面的命令:

db.shiyanlou.find({"name":{$type:"string"}})

limit()与skip()

读取指定数量的数据记录limit()

db.shiyanlou.find().limit(1)

读取一条记录,默认是排在最前面的那一条被读取

读取时跳过指定数量的数据记录skip()

db.shiyanlou.find().limit(1).skip(1)

当然,还可以添加 find 的查找条件的参数,以便进行更精确的查找。

排序sort()

有升序和降序,升序用1表示,降序用-1表示

db.shiyanlou.find().sort({"time":1})

索引ensureIndex()

索引也有升序和降序

db.shiyanlou.ensureIndex()

ensureIndex()的可选参数

参数类型描述
background Boolean 建立索引要不要阻塞其他数据库操作,默认为 false
unique Boolean 建立的索引是否唯一,默认 false
name string 索引的名称,若未指定,系统自动生成
dropDups Boolean 建立唯一索引时,是否删除重复记录,默认 flase
sparse Boolean 对文档不存在的字段数据不启用索引,默认 false
expireAfterSeconds integer 设置集合的生存时间,单位为秒
v index version 索引的版本号
weights document 索引权重值,范围为 1 到 99999
default-language string 默认为英语
language_override string 默认值为 language
db.shiyanlou.ensureIndex({"user_id":1,"name":1},{background:1})

聚合aggregate()

db.COLLECTION_NAME.aggregate({
$match:{x:1},
{limit:NUM},
$group:{_id:$age}
})

这些参数都可选

  • $match:查询,跟 find 一样;

  • $limit:限制显示结果数量;

  • $skip:忽略结果数量;

  • $sort:排序;

  • $group:按照给定表达式组合结果。

> db.shiyanlou.aggregate([{$group:{_id:"$name", user:{$sum:"$user_id"}}}])
?

$name 意为取得 name 的值。

聚合表达式

名称描述
$sum 计算总和
$avg 计算平均值
min 和min和max 计算最小值和最大值
$push 在结果文档中插入值到一个数组
$addToSet 在结果文档中插入值到一个数组,但不创建副本
$first 根据资源文档的排序获取第一个文档数据
$last 根据资源文档的排序获取最后一个文档数据

管道

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

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

聚合框架中常用的几个操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。

  • $match:用于过滤数据,只输出符合条件的文档。$match 使用 MongoDB 的标准查询操作。

  • $limit:用来限制 MongoDB 聚合管道返回的文档数。

  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。

  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

  • $group:将集合中的文档分组,可用于统计结果。

  • $sort:将输入文档排序后输出。

  • $geoNear:输出接近某一地理位置的有序文档。

  •  

以上是关于mongodb基本操作的主要内容,如果未能解决你的问题,请参考以下文章

ios - Heroku 和 MongoDb 上的自定义解析服务器错误 3080:JSON 文本没有以数组或对象开头,并且允许未设置片段的选项

mongodb关联查询

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

无法在 MongoDB(猫鼬)文档中追加数组