MongoDB常用命令

MongoDB

设计

如果还用以前关系数据库的思路来建模,有时会适得其反。在 MongoDB 中提倡的设计思路可能是建立一个客户表,在表中包含业务需要的尽可能多的数据信息,这样最终会产生一些冗余信息,但是在 NoSQL 的世界里是提倡这样做的。

安装与配置

安装

Bash
sudo apt-get install gnupg
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
sudo apt-get update
sudo apt install mongodb-org
sudo systemctl start mongod.service
sudo systemctl enable mongod
sudo systemctl status mongod
mongo --eval 'db.runCommand({ connectionStatus: 1 })'
Bash
cat > /etc/yum.repos.d/mongodb-org-5.0.repo << End
[mongodb-org-5.0] 
name=MongoDB Repository 
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/ 
gpgcheck=1 
enabled=1 
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
End
yum install -y mongodb-org
sudo systemctl start mongod.service
sudo systemctl enable mongod
sudo systemctl status mongod
mongo --eval 'db.runCommand({ connectionStatus: 1 })'

配置常用配置项

MongoDB的配置文件路径为 /etc/mongod.conf

MongoDB 官方配置文件手册

配置用户名密码

内存使用

数据库操作

"show dbs" 命令可以显示所有数据的列表。

执行 "db" 命令可以显示当前数据库对象或集合。

运行"use db"命令,可以连接到一个指定的数据库,如果数据库不存在,则创建数据库。
如果数据库不存在,使用use创建,需要插入数据才能在show dbs命令中看到。

在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

切换到数据库后执行 db.dropDatabase() 可以删除数据库。

集合操作

查看集合

show collections / show tables

删除集合

db.collection.drop()

创建集合

db.createCollection(name, options)

在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。

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

插入到集合 db.name.insert({"key":"value"})

文档操作

插入文档

JavaScript
db.COLLECTION_NAME.insert(document)
// 或
db.collection.insertOne() 
db.collection.insertMany()

insert: 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。

JavaScript
db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)
JavaScript
db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

更新文档

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

实例

JavaScript
// 只更新第一条记录:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );

// 全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );

// 只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );

// 全部添加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

// 全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );

// 只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

删除文档

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

查询文档

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

索引

索引能够提高读操作及查询性能。没有索引,MongoDB 必须扫描集合中的每一个文档,然后选择与查询条件匹配的文档,这种全表扫描的方式是非常低效的。

MongoDB 索引的数据结构也是 B+ 树,它能存储一小部分集合的数据,具体来说就是存储集合中建有索引的一个或多个字段的值,而且按照值的升序或降序排列。对于一个查询来说,如果存在合适的索引,MongoDB 能够利用这个索引减少文档的扫描数量,这种查询是非常高效的。每个集合都有一个叫做 _id 的单字段索引。

如果对一个值为数组类型的字段创建索引,则会默认对数组中的每一个元素创建索引。

创建索引

db.collection.createIndex(keys, options)
  • Key 值为要创建的索引字段,
  • 1 为指定按升序创建索引,指定为 -1 即按降序来创建索引。

删除索引

db.collection.dropIndex(keys)
  • Key 值为要删除的索引字段,

语句比较

操作 格式 范例 RDBMS中的类似语句
等于 {<key>:<value>} db.col.find({"by":"菜鸟教程"}).pretty() where by = 'NAME'
小于 {<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

https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/

命名规范

数据库

数据库名可以是满足以下条件的任意UTF-8字符串:

  • 不能是空字符串("")。
  • 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
  • 应全部小写。
  • 最多64字节。

文档

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .和$有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

集合

合法的集合名

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。 
RDBMS MongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )

数据类型

下表为MongoDB中常用的几种数据类型。

数据类型 描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Array 用于将数组或列表或多个值存储为一个键。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值。
Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。
Binary Data 二进制数据。用于存储二进制数据。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。

ObjectId

ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:

  • 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
  • 接下来的 3 个字节是机器标识码
  • 紧接的两个字节由进程 id 组成 PID
  • 最后三个字节是随机数

相关连接

Motor asyncio API

Preventing NoSQL Injections In Your Code

As with most injection attacks, NoSQL injections can be prevented by using proper filtering techniques. There are a few things I recommend to harden your mongo instance and application code. This will limit or prevent injections in your code, regardless of language or framework.

  1. Don't use the Mongo where, mapReduce, or group with user supplied data. These are all JavaScript injectable functions. Where clauses can almost always be re-written as normal queries, perhaps using expr instead. See the Mongo documentation.
  2. Use a typed model. Typed models will automatically stop some injections by converting user input to the expected type, such as string or int. Note that in my sample project, I did use a typed model and it did not prevent the attacks shown, so it is of limited use (but better than not using a typed model).
  3. Set javascriptEnabled to false in your mongod.conf, if you can. This will disable JavaScript execution in your instance and remove that class of attacks.
  4. Always strongly validate user supplied data - this will help prevent a lot more than just NoSQL attacks! Use libraries like mongo-sanitize (node) or similar libraries on all user supplied information, including cookie values and data from the browser. If you can't find a library, then enforce type and escape problematic characters within input like single and double quotes. This is difficult to get right, so only do this if your language and framework don't offer good sanitization libraries.
qrcode

创建时间:2022-02-11 01:11:34

最后修改:2023-03-31 06:36:48