MongoDB是一个著名的NoSQL数据库,顾名思义就是不使用SQL的数据库,目前在很多场景都有使用。如果你不喜欢使用笨拙的各种SQL数据库,可以尝试使用一下MongoDB,会有不一样的感受。本文就是一篇简单的Windows下的安装和使用教程。
下载和安装
首先,先到MongoDB官网下载页下载社区版的服务器,由于这里是Windows系统,所以当然下载Windows版本的。注意我们要下载的是社区版,而不是导航条第一个的Atlas。如你所见,MongoDB官网是一个商业化的网站,Atlas正是它提供的一个商业版服务,可以让我们连接到他们的服务器。
下载页面
具体版本默认第一个就可以了,功能最全,带有SSL支持。注意三个版本都是64位的,所以32位的操作系统无法运行。下载完成之后安装即可,大约150M左右的安装包,很快就可以安装完毕。
配置和启动
对于我来说,我将其安装到了D:\Program Files\MongoDB
。等到安装完成,打开D:\Program Files\MongoDB\Server\3.4\bin
就会发现MongoDB的一系列程序,主要用到的就是mongo.exe
(客户端)和mongod.exe
(服务端)。为了使用方便,最好把这个路径添加到环境变量中,以后就可以直接在终端中使用这些命令了。首先要做的事情当然是启动服务端。在终端直接执行mongod
命令即可。
mongod
然后你就会发现如图所示的错误。
找不到数据文件夹
当然具体错误图里面说的很清楚了,没有数据文件夹。默认Windows版本,会在你安装盘符下寻找data/db
文件夹作为数据文件夹,我的D盘上自然没有,所以会出现错误。解决办法很简单,在命令上添加--dbpath
参数即可。
mongod --dbpath d:\test\mongodb\data
当然还可以使用配置文件。配置文件名字可以随便起,但是格式必须是YAML格式的。例如我希望让可执行文件目录下的data
文件夹作为数据文件夹,并且对于每个单独的数据库都有自己的目录,就可以这么配置(别忘了创建对应文件夹)。关于配置文件的详细文档可以参考官方Configuration File Options。
storage:
dbPath: data
directoryPerDB: true
配置完成后,使用-f
或者--config
参数来指定配置文件。
mongod --config /etc/mongod.conf
mongod -f /etc/mongod.conf
这样,MongoDB服务器就可以成功启动了。
注册为Windows服务
每次启动都要输入命令很麻烦,MongoDB提供了注册为Windows服务的功能。本来一开始我是用的winsw来注册服务的,然后发现MongoDB官方就带了这个功能。所以来介绍一下。
其实很简单,打开上面介绍的配置文件,然后添加下面一节内容,具体名称自己修改。这里用户名和密码不是必须的。这里日志设置是必须的,不然会提示无法安装Windows服务。
storage:
dbPath: 'D:\Program Files\MongoDB\Server\3.4\data'
directoryPerDB: true
processManagement:
windowsService:
serviceName: MongoDB
displayName: MongoDB
description: MongoDB
serviceUser: <string>
servicePassword: <string>
systemLog:
destination: file
path: 'D:\Program Files\MongoDB\Server\3.4\mongod.log'
然后在运行服务端的时候添加--install
参数,而且这里的配置文件路径必须使用绝对路径。别忘了使用管理员权限的cmd或者Powershell来运行。
mongod -f 'D:\Program Files\MongoDB\Server\3.4\config.yaml' --install
安装之后的服务默认是开机自启的,不过没有启动,所以还需要我们手动启动。手动在服务中启动,或者在管理员权限的Powershell中执行下面的命令。
Start-Service MongoDB
客户端连接
如果没有修改端口号等配置的话,可以直接连接。
PS C:\WINDOWS\system32> mongo
MongoDB shell version v3.4.10
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
Server has startup warnings:
2017-11-20T04:48:38.134+0800 I CONTROL [initandlisten]
2017-11-20T04:48:38.134+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-11-20T04:48:38.134+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2017-11-20T04:48:38.135+0800 I CONTROL [initandlisten]
>
Linux下安装和配置
安装
由于我正好有一个Dedicenter的服务器,所以顺便来试试Linux下安装。Linux下安装其实也很简单,使用对应的包管理器可以比较方便的安装和启动。例如我的服务器是CentOS 7的系统,所以使用yum包管理器来安装软件。下面的命令同时安装了客户端和服务器端。
$ sudo yum install mongodb-server mongodb
当然我安装完了之后发现了一个问题,那就是CentOS自带的MongoDB版本比较低,现在的版本是3.4,而自带的版本是2.6.所以还是需要自己安装最新版的。具体方法需要搜索。对于CentOS 来说,首先需要创建社区源的文件/etc/yum.repos.d/mongodb-org-3.4.repo
,内容如下。
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
然后安装mongodb-org
软件包,会包括客户端、服务端、shell工具等四个软件包。
$ sudo yum install mongodb-org
如果对应的系统还启用了SELinux,那么还需要做一些额外工作,这些工作就需要查看官方文档Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux了。我的服务器没有SELinux功能,所以不需要这额外的步骤了。
配置并启动
Linux下,MongoDB的数据文件在/var/lib/mongo
下,日志文件在/var/log/mongodb
下,这些都不需要更改。如果有需要的话,别忘了设置对应的权限。
首先需要编辑一下配置文件/etc/mongod.conf
。先来设置一下监听IP,由于这是我的服务器,我希望可以在外网访问数据库,所以把IP这一行注释掉,或者修改成0.0.0.0
。其余配置按需求更改。
net:
port: 27017
# bindIp: 127.0.0.1 # Listen to local interface only, comment to listen on all interfaces.
然后启动服务端。
sudo systemctl enable mongod
sudo systemctl start mongod
然后输入mongo
命令来连接。如果是连接其他主机的服务器,需要使用额外的参数。
mongo -host XXX.XX.XXX.XXX -port 27017
基本使用
用户授权
在前面我们一直都没有设置用户名和密码,这可能导致安全问题,登录客户端的时候也同时给了警告。所以我们第一件事情就是设置用户名和密码。这部分可以参考官方文档Enable Auth。
首先先以默认方式登录,然后切换到管理员数据库并新建管理员用户。
use admin
db.createUser(
{
user: "admin",
pwd: "12345678",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
然后在重启服务端的时候同时添加--auth
参数,或者在配置文件中设置。
security:
authorization: enabled
服务器启用验证之后,客户端在登录的时候也需要验证。可以在启动的时候通过参数来验证。
mongo --port 27017 -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"
或者先以无权限方式登录,然后在进行验证。
use admin
db.auth("myUserAdmin", "abc123" )
当然,实际情况中我们肯定不会使用管理员去登录一般数据库(实际上MongoDB也不允许,管理员只有创建用户和角色的权限),所以还需要创建一个普通用户进行访问。在你使用的数据库中创建一个用户,并赋予合适的权限即可。登录方式基本同上,只不过验证数据库改一下就行。
use test
db.createUser(
{
user: "myTester",
pwd: "xyz123",
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "reporting" } ]
}
)
当然,如果是开发和测试,建立一个万能的管理员用户更加省时。
use admin
db.createUser(
{
user: "superuser",
pwd: "12345678",
roles: [ "root" ]
}
)
插入数据
先来说说MongoDB的增删查改。这一部分的官方文档是MongoDB CRUD Operations,这一块的文档做的非常好,还配有Web控制台可以连接到它的示例数据库,所以我们可以一边阅读文档一边测试命令,非常方便。
首先先选定一个数据库,如果该数据库不存在,会创建这个数据库。
use hello
先来看看插入操作,主要有以下两个方法,分别用于一次性插入一个或多个数据。如果集合不存在,会首先创建这个集合。
下面是一个简单的例子。插入的数据类似JSON格式。
> db.user.insertOne({id:1,name:'yitian',age:24})
{
"acknowledged" : true,
"insertedId" : ObjectId("5a12bc37f8fe60078d1a24fe")
}
> db.user.insertOne({id:2,name:'zhang3',age:25})
{
"acknowledged" : true,
"insertedId" : ObjectId("5a12bc93f8fe60078d1a24ff")
}
如果要使用insertMany
插入多个数据,需要使用[]
来传递一个数组。这是官方文档的例子。
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
查询数据
首先准备一些示例数据。
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
如果要查询所有数据,直接传递一个空对象。
db.inventory.find( {} )
如果用具体的条件来查询,直接传递具体的键值对{ <field1>: <value1>, ... }
即可。
db.inventory.find( { status: "D" } )
如果使用条件查询的话,需要传递查询属性、运算符以及查询条件{ <field1>: { <operator1>: <value1> }, ... }
。
# 查询stauts是A或D的
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
# 查询status是A,且qty小于30的
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
# 查询status是A或qyt小于30的
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
# 更复杂的查询
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )
更新数据
更新操作主要使用以下三个函数,用于更新一个、多个或者替换数据。<filter>
就是切面介绍的查询条件,其余的将在下面介绍。
- db.collection.updateOne(<filter>, <update>, <options>)
- db.collection.updateMany(<filter>, <update>, <options>)
- db.collection.replaceOne(<filter>, <replacement>, <options>)
先来看看更新一个数据,需要用到$set
操作符,用来设置新属性。$currentDate
操作符用于设置最后修改时间,如果lastModified
属性不存在,就会添加这个属性并设置为当前时间。
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
类似的,是更新多条数据。
db.inventory.updateMany(
{ "qty": { $lt: 50 } },
{
$set: { "size.uom": "in", status: "P" },
$currentDate: { lastModified: true }
}
)
最后是替换数据。
db.inventory.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)
最后来说说<option>
。目前这个选项只有一个upsert : true
,如果设置为true,那么如果没有查询到相应的数据,会将更新的数据作为新数据插入到数据库中。
删除数据
删除数据相对来说很简单,语法和前面基本类似。所以直接来看李子坝。
首先是删除所有数据。
db.inventory.deleteMany({})
删除符合条件的所有数据。
db.inventory.deleteMany({ status : "A" })
删除单条数据。
db.inventory.deleteOne( { status: "D" } )
编程使用MongoDB
官方文档MongoDB CRUD Operations做的很不错的一点就是包含了多种语言的范例,基本上支持了现在所有的主流语言。
使用Python
官方推荐使用PyMongo库来操作MongoDB。首先需要安装。文档可以参考PyMongo 3.5.1 Documentation。
pip install PyMongo
简单的增删查改例子如下。
from pymongo import MongoClient
from pprint import pprint
# 连接数据库
client = MongoClient('localhost', 27017)
# 选择数据库
db = client['hello']
# 获取集合
user = db.user
# 插入数据
user.insert_one({"_id": 1, "name": "yitian", "age": 24})
user.insert_one({"_id": 2, "name": "zhang3", "age": 25})
user.insert_one({"_id": 3, "name": "li4", "age": 26})
# 更新数据
user.update_one({"_id": 1}, {"$set": {"name": "易天"}})
user.update_many({}, {"$inc": {"age": 1}})
# 查询数据
yitian = user.find_one({"name": "yitian"})
yitian = user.find_one({"_id": 1})
pprint(yitian)
print("------所有数据--------")
for u in user.find():
pprint(u)
print("------年龄大于25的--------")
for u in user.find({"age": {"$gt": 25}}):
pprint(u)
# 删除所有数据
user.remove({})
使用C#
C#和Kotlin是我最喜欢的两门语言。所以顺便来看看如何用C#访问MongoDB。对应的官网文档是MongoDB .NET Driver。
首先需要安装NuGet包,如果使用Visual Studio的话非常简单,右键点击项目,选择管理安装的NuGet包,然后搜索并安装MongoDB即可。下面是个简单的例子。
public static void Sample()
{
var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("hello");
var user = db.GetCollection<BsonDocument>("user");
user.InsertOne(new BsonDocument
{
{
"name", "yitian"
},
{
"_id", 1
},
{
"age", 25
}
});
user.InsertOne(new BsonDocument
{
{
"name", "li4"
},
{
"_id", 3
},
{
"age", 24
}
});
Console.WriteLine("查询单条数据");
var filter = Builders<BsonDocument>.Filter.Eq("_id", 1);
Console.WriteLine(
user.Find(filter).First()
);
Console.WriteLine("更新用户姓名");
user.FindOneAndUpdate(filter, Builders<BsonDocument>.Update.Set("name", "易天"));
Console.WriteLine("条件查询大于25的");
filter = Builders<BsonDocument>.Filter.Gte("age", 25);
user.Find(filter).ToList().ForEach(e => Console.WriteLine(e));
Console.WriteLine("所有数据");
user.Find(new BsonDocument()).ToList().ForEach(e => Console.WriteLine(e));
user.DeleteMany(new BsonDocument());
}
图形客户端
最后来介绍一下几个图形客户端,方便我们对数据进行可视化处理。
Compass
第一个就是MongoDB官方的图形客户端Compass,用起来还可以。
MongoBooster
第二个叫MongoBooster,是一个MongoDB的IDE,智能提示和补全比较方便,同时支持流式API方便查询。
Robo 3T
第三个是Robo 3T,原名叫做Robomongo,是一个轻量级图形客户端。如果希望更多功能,还可以下载使用Studio 3T,一个智能IDE。
最后说一下我对MongoDB的感受。它是一个比较轻量级的NoSQL数据库,存储序列化的数据很合适,但是多表查询功能比较弱,要想做到SQL数据库那种复杂的多表查询比较困难。但是如果是个人小项目的话,还是非常推荐使用的,用起来心理作用上比SQL数据库的逼格还是要高一些的。