一、通用方法和帮助获取

1.1 获取帮助

-- mongo提供了 help 功能,可以帮助查看一些命令

help
help
db.help()           help on db methods
db.mycoll.help()    help on collection methods
sh.help()           sharding helpers
rs.help()           replica set helpers

db.help();
DB methods:
db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [just calls db.runCommand(...)]
--切换到 'admin'数据库,并运行命令 [只是调用 db.runCommand(...)]
db.aggregate([pipeline], {options}) - performs a collectionless aggregation on this database; returns a cursor
db.auth(username, password)
db.cloneDatabase(fromhost) - will only function with MongoDB 4.0 and below
db.createUser(userDocument)
db.currentOp() displays currently executing operations in the db
db.dropDatabase()
...

db.t1.help();
DBCollection help
db.t1.find().help() - show DBCursor help
db.t1.bulkWrite( operations, <optional params> ) - bulk execute write operations, optional parameters are: w, wtimeout, j
db.t1.count( query = {}, <optional params> ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMS
db.t1.createIndex(keypattern[,options])
...
db.[TAB][TAB]
db.t1.[TAB][TAB]

1.2 常用操作

//查看当前 db版本
db.version()

//显示当前数据库
db
db.getName()

// 查询所有数据库
show dbs

//切换数据库
use local

// 显示当前数据库状态,查看 local数据
use local
db.stats()  #默认按 byte显示,db.stats(1024)则按 kb显示数据
{
  "db" : "local",
  "collections" : 1,
  "views" : 0,
  "objects" : 2,
  "avgObjSize" : 2767,
  "dataSize" : 5534,
  "storageSize" : 36864,
  "indexes" : 1,
  "indexSize" : 36864,
  "totalSize" : 73728,
  "scaleFactor" : 1,
  "fsUsedSize" : 37103575040,
  "fsTotalSize" : 43976765440,
  "ok" : 1
}

//查看当前数据库的连接机器地址
db.getMongo()
connection to 127.0.0.1:27017

// 指定数据库进行连接:(默认连接本机 test数据库)
mongo 192.168.1.153/admin
[mongod@mongodb ~]$ mongo 192.168.1.153/admin

1.3 库和表的操作

// 建库,如果数据库不存在,则创建数据库,否则切换到指定数据库
use test

// 删除
db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }

方法 1:

mongo -uroot -p000000 admin
admin> use app
db.createCollection('a')
db.createCollection('b')

--如果要查看已有集合,可以使用 show collections  show tables 命令:
show tables;
a
b

方法 2:当插入一个文档的时候,一个集合就会自动创建。

admin> use app
switched to db app
app> db.c.insert({username:"mongodb"})
WriteResult({ "nInserted" : 1 })

app> show collections
a
b
c

app> db.c.find()
{ "_id" : ObjectId("5743c9a9bf72d9f7b524713d"), "username" : "mongodb" }

// 删除集合
app> use app
switched to db app
app> db.a.drop() //删除集合
true

// 重命名集合,将集合 b重命名为 bb
db.b.renameCollection("bb")
{ "ok" : 1 }
show tables;
bb
c

二、基本数据类型

在概念上,MongoDB的文档与 Javascript的对象相近,因而可以认为它类似于 JSON。JSON(http://www.json.org)是一种简单的数据表示方式:其规范仅用一段文字就能描述清楚,且仅包含六种数据类型。

这样有很多好处:易于理解、易于解析、易于记忆。然而从另一方面说,因为只有 null、布尔、数 字、字符串、数字和对象这几种数据类型,所以 JSON的表达能力有一定的局限。

虽然 JSON具备的这些类型已经具有很强的表现力,但绝大数应用(尤其是在于数据库打交道时)都还需要其他一些重要的类型。例如,JSON没有日期类型,这使得原本容易日期处理变得烦人。另外,JSON只有一种数字类型,无法区分浮点数和整数,更别区分 32位和 64位了。再者 JSON无法表示其他一些通用类型,如正则表达式或函数。

MongoDB在保留了 JSON基本键 /值对特性的基础上,添加了其他一些数据类型。在不同的编程语言下,这些类型的确切表示有些许差异。下面说明了 MongoDB支持的其他通用类型,以及如何正在文档中使用它们。

1、null:用于表示空或不存在的字段

d={'x':null}

2、布尔型:true和 false

d={'x':true,'y':false}

3、数值

d={'x':3,'y':3.1415926}

4、字符串

d={'x':'egon'}

5、日期

d={'x':new Date()}
d.x.getHours()

6、正则表达式

d={'pattern':/^egon.*?nb$/i}

正则写在 // 内,后面的 i 代表:

i 忽略大小写

m 多行匹配模式

x 忽略非转义的空白字符

s 单行匹配模式

7、数组

d={'x':[1,'a','v']}

8、内嵌文档

user={'name':'egon','addr':{'country':'China','city':'YT'}}
user.addr.country

9、对象 id:是一个 12字节的 ID,是文档的唯一标识,不可变,总共有 24位 16进制数构成,也就是 12个字节。

d={'x':ObjectId()}

_id和 Objectid

Objectid,类似于唯一的主键,包含 12个字节,总共有 24位 16进制数构成,也就是 12个字节。

示例:

db.fruit.insertOne({name: "apple"})
db.fruit.find()
{ "_id" : ObjectId("669f4657324f31a52cd497a1"), "name" : "apple" }
669f4657 324f31 a52c d497a1

注意:这个类型是不可以被 JSON序列化的

这是 MongoDB生成的类似关系型 DB表主键的唯一 key,具体由 24个 bit组成:

0-8字节是 unix时间戳

9-14字节的机器码,表示 MongoDB实例所在机器的不同

15-18字节的进程 id,表示相同机器的不同 MongoDB进程

19-24字节是随机数

由于 ObjectId中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,可以通过 getTimestamp() 来获取文档的创建时间戳

// 返回时间戳
ObjectId("669f4657324f31a52cd497a1").getTimestamp()
ISODate("2024-07-23T05:57:43Z")

// 返回字符串
ObjectId("669f4657324f31a52cd497a1").str
669f4657324f31a52cd497a1

// 返回大于某天的数据条数
// 在线转换格式:https://steveridout.github.io/mongo-object-time/
db.fruit.find({_id:{$gt:ObjectId("669f46000000000000000000")}}).count()
1

python实现时间戳的转换

import time

def id2time(object_id):
    timeStamp = int(object_id[:8], 16)
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timeStamp))

三、使用 insert 完成插入操作

操作格式:

db.<集合>.insertOne(<JSON对象>)
db.<集合>.insertMany([<JSON 1>, <JSON 2>, ...<JSON n>])

示例:

db.fruit.insertOne({name: "apple"})

db.fruit.insertMany([
  {name: "apple"},
  {name: "pear"},
  {name: "orange"}
])

批量插入数据:

for(i=0;i<10000;i++){
  db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()});
}

四、使用 find 查询文档

关于 find:

find 是 MongoDB 中查询数据的基本指令,相当于 SQL 中的 SELECT。find 返回的是游标。

find() 方法以非结构化的方式来显示所有文档,如果需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:db.col.find().pretty()

语法格式:

db.collection.find(query, projection)
  • query:可选,使用查询操作符指定查询条件
  • projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)

find 示例:

db.movies.find( { "year" : 1975 } ) //单条件查询
db.movies.find( { "year" : 1989, "title" : "Batman" } ) //多条件 and查询
db.movies.find( { $and : [ {"title" : "Batman"}, { "category" : "action" } ] } ) // and的另一种形式
db.movies.find( { $or: [{"year" : 1989}, {"title" : "Batman"}] } ) //多条件 or查询
db.movies.find( { "title" : /^B/} ) //按正则表达式查找

五、查询条件对照表

SQL MSQL
a=1 {a:1}
a<>1 {a:{$ne:1}}
a>1 {a:{$gt:1}}
a≥1 {a:{$gte:1}}
a<1 {a:{$lt:1}}
a≤1 {a:{$lte:1}}

六、查询逻辑对照表

SQL MSQL
a=1 and b=1 {a: 1, b: 1}或 {$and: [{a: 1}, {b: 1}]}
a = 1 OR b = 1 {$or: [{a: 1}, {b: 1}]}
a IS NULL {a: {$exists: false}}
a IN (1, 2, 3) {a: {$in: [1, 2, 3]}}

七、查询逻辑运算符

  • $lt:存在并小于
  • $lte:存在并小于等于
  • $gt:存在并大于
  • $gte:存在并大于等于
  • $ne:不存在或存在但不等于
  • $in:存在并在指定数组中
  • $nin:不存在或不在指定数组中
  • $or:匹配两个或多个条件中的一个
  • $and:匹配全部条件

八、使用 find 搜索子文档

find 支持使用 field.sub_field 的形式查询子文档。假设有一个文档:

db.fruit.insertOne({
  name: "apple",
  from: {
    country: "China",
    province: "Guangdong"
  }
})

正确写法:

db.fruit.find( { "from.country" : "China" } )

九、使用 find 搜索数组

find 支持对数组中的元素进行搜索。假设有一个文档:

db.fruit.insert([
  { "name" : "Apple", color: ["red", "green" ] },
  { "name" : "Mango", color: ["yellow", "green"] }
])

查看单个条件:

db.fruit.find({color: "red"})

查询多个条件:

db.fruit.find({$or: [{color: "red"}, {color: "yellow"}]})

十、使用 find 搜索数组中的对象

考虑以下文档,在其中搜索

db.movies.insertOne({
  "title" : "Raiders of the Lost Ark",
  "filming_locations" : [
    { "city" : "Los Angeles", "state" : "CA", "country" : "USA" },
    { "city" : "Rome", "state" : "Lazio", "country" : "Italy" },
    { "city" : "Florence", "state" : "SC", "country" : "USA" }
  ]
})

// 查找城市是 Rome 的记录
db.movies.find({"filming_locations.city": "Rome"})

十一、使用 find 搜索数组中的对象 $elemMatch

在数组中搜索子对象的多个字段时,如果使用 $elemMatch,考虑以下两个查询:

db.getCollection('movies').find({
  "filming_locations.city": "Rome",
  "filming_locations.country": "USA"
})

$elemMatch,它表示必须是同一个子对象满足多个条件。

db.movies.insertOne({
  "title" : "11111",
  "filming_locations" : [
    { "city" : "bj", "state" : "CA", "country" : "CHN" },
    { "city" : "Rome", "state" : "Lazio", "country" : "Italy" },
    { "city" : "tlp", "state" : "SC", "country" : "USA" }
  ]
})

db.getCollection('movies').find({
  "filming_locations": { $elemMatch:{"city":"bj", "country": "CHN"} }
})

十二、控制 find 返回的字段

find 可以指定只返回指定的字段

  • _id 字段必须明确指明不返回,否则默认返回
  • 在 MongoDB 中我们称这为投影(projection)
db.movies.find({},{"_id":0, title:1})    #查询集合中所有数据,只显示 title
db.movies.find({title:"ddd"},{"year":0,"category":0})  #查询 name=bbb的数据,其中 year和 category两个字段不显示

十三、使用 remove 删除文档

remove 命令需要配合查询条件使用

  • 匹配查询条件的文档会被删除
  • 指定一个空文档条件会删除所有文档
  • 以下示例:
db.testcol.remove( { a : 1 } ) // 删除 a 等于 1的记录
db.testcol.remove( { a : { $lt : 5 } } ) // 删除 a 小于 5的记录
db.testcol.remove( { } ) // 删除所有记录
db.testcol.remove() //报错

十四、使用 updateOne 更新文档

Update 操作执行格式:

db.<集合>.update(<查询条件>, <更新字段>)
  • 以以下数据为例:
db.fruit.insertMany([
  {name: "apple"},
  {name: "pear"},
  {name: "orange"}
])

db.fruit.updateOne({name: "apple"}, {$set: {from: "China"}})

十五、使用 update 更新文档

  • 使用 updateOne 表示无论条件匹配多少条记录,始终只更新第一条
  • 使用 updateMany 表示条件匹配多少条就更新多少条
  • updateOne/updateMany 方法要求更新条件部分必须具有以下之一,否则将报错:
  • $set/$unset
  • $push/$pushAll/$pop
  • $pull/$pullAll
  • $addToSet
// 报错
db.fruit.updateOne({name: "apple"}, {from: "China"})
2022-09-25T17:27:15.153+0800 E QUERY   [js] Error: the update operation document must contain atomic operators : DBCollection.prototype.updateOne@src/mongo/shell/crud_api.js:542:1
@(shell):1:1

update的语法:

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:可选,抛出异常的级别

示例:

(1) 造数据

for(i=1;i<=10;i++){
  db.user.insert({_id:i,name:"user"+i,age:10+i})
}

(2) 更新 name=user1 的文档的全部数据为 name=user11

db.user.find({name:"user1"})
{ "_id" : 1, "name" : "user1", "age" : 11 }

db.user.update({name:"user1"},{name:"user11"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

db.user.find({name:"user11"})
{ "_id" : 1, "name" : "user11" }

(3) 将 name=user2 的文档设置为 “MongoDB”

db.user.update({'name':'user2'},{$set:{'name':'MongoDB'}})

(4) 更新一个字段的值,age=另一个字段的值

db.user.find({'age': 20}).forEach(
  function(item){
    db.user.update({"_id":item._id},{"$set":{"age":item._id}},false,true)
  }
)

(5) 使用 update更新 n条记录

db.test.update({'title':'MongoDB'},{$set:{'title':'New Mongo'}},{multi:true}) == db.test.update({'title':'MongoDB'},{$set:{'title':'New Mongo'}},0,1)

(6) 更新方法 $inc

为一个字段添加加上一个值,这个方法只能对数字操作,也就是说只能给数字加上一个值,当然这个值可以是负数。

db.user.update({name:"user2"},{$inc:{age:10}})  ## name为 user2的年龄 age加上 10
db.user.update({name:"user6"},{$inc:{age:-4}})  ## name为 user6的年龄 age减去 4

(7) 更新方法 $unset

语法:

db.collection.update({ field: value1 }, { $unset: { field1: <arg> } });

参数 arg可以使用 true或者空字符串 "",这样都会删除一个字段。

db.user.update({name:"user2"},{$unset:{sex:1}})

(8) 更新字段名称 $rename

语法:

db.collection.update({$rename: { <old name1>: <newname1>, <old name2>: <new name2>, ... } })

为文档中的一个或者多个字段改名。

db.test.update({_id:1},{$rename:{ary:"aryNew"}}) ## _id=1 ary字段改名为 aryNew

十六、使用 update 更新数组

  • $push: 增加一个对象到数组底部
  • $pushAll: 增加多个对象到数组底部
  • $pop: 从数组底部删除一个对象
  • $pull: 如果匹配指定的值,从数组中删除相应的对象
  • $pullAll: 如果匹配任意的值,从数据中删除相应的对象
  • $addToSet: 如果不存在则增加一个值到数组

示例:

(1) 更新方法 $push,$pushAll

-- $push是向数据中添加新的数据,但是 {$push:{field:value}} 中的 field应为数组类型的,如果 field不是数组类型的,就会出错,如果 filed不存在,则创建该数组类型并插入数据,而 $pushAll是向数组中添加数组数据

语法:

db.collection.update(<query>,{ $push:{ <field>: <value> } })

将一个数字存入一个数组,分为三种情况,如果该字段存在,则直接将数字存入数组;如果该字段不存在,创建字段,并且将数字插入该数组;如果更新的字段不是数组,会报错。

db.test.insert({ "_id" : 1, "ary" : [ 1, 2, 3, 4 ] } )
db.test.update({_id:1},{$push:{ary:5}})     ##数组存在 直接存入
{ "_id" : 1, "ary" : [ 1, 2, 3, 4, 5 ] }
db.test.insert({"_id":2})
db.test.update({_id:2},{$push:{ary:6}})     ##数组不存在,创建数组并存入

(2) 更新方法 $pop

语法:

db.collection.update( {field: value }, { $pop:{ field:<arg> } } )

删除数组最后一个或者第一个元素。如果参数 arg设置为 1,删除最后一个元素,如果设置为 -1,则删除第一个元素。

{ "_id" : 2, "ary" : [ 6, 7 ], "text": "test" }
db.test.update({_id:2},{$pop:{ary:1}})   ##删除数组 ary的最后一个元素
{ "_id" : 2, "ary" : [ 6 ], "text" :"test" }

(3) 更新方法 $pull,$pullAll

语法:

db.collection.update( { field: <query> },{ $pull: { field: <query> } } );

删除数组中的一个元素,如果删除的字段不是数组,会报错。

db.test.update({_id:1},{$pull:{ary:4}})  ##删除数组 ary中的 4

(4) 更新方法 $addToSet

语法:

db.collection.update( { field: value }, {$addToSet: { field: value1 } } );

与 $push功能相同,将一个数字存入数组,不同的是如果数组中有这个数字,将不会插入,只会插入新的数据,同样也会有三种情况,与 $push相同。

db.test.update({_id:2},{$addToSet:{ary:7}})   ## ary中没有 7,插入成功,有则插入失败
db.test.update({_id:2},{$addToSet:{ary:6}})    ##数组不存在,创建数组并存入
db.test.update({_id:1},{$addToSet:{ary:[6,7,8]}}) ##多个值一起存入
{ "_id" : 2, "ary" : [ 6, 7, [ 6, 7, 8 ] ] }

十七、使用 drop 删除集合

  • 使用 db.<集合>.drop() 来删除一个集合
  • 集合中的全部文档都会被删除
  • 集合相关的索引也会被删除
db.colToBeDropped.drop()

十八、使用 dropDatabase 删除数据库

  • 使用 db.dropDatabase() 来删除数据库
  • 数据库相应文件也会被删除,磁盘空间将被释放
use tempDB
db.dropDatabase()
show collections // No collections
show dbs // The db is gone