[toc]本篇将描述服务端上MongoDB的简单使用,包括基础的安装和连接数据库,对数据的增删查改等. 选择MongoDB是为了以后和ET服务端框架进行对接. 由于我使用的开发环境是Centos7 那么这里我选择安装Red Hat的发行版,官方有完整的新手引导页面,就不建议百度搜索了,其他系统的话,去找对应系统的官方文档即可. Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux

安装MongoDB

这里将使用yum命令进行安装,所以先创建一个repo文件 vim /etc/yum.repos.d/mongodb-org-4.0.repo --------------编辑内容 按I键进入编辑 [mongodb-org-4.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc --------------编辑完成 按ESC键退出编辑 :wq 回车 --------------安装最新版本的MongoDB yum install -y mongodb-org

运行MongoDB

service mongod start

设置开机启动

chkconfig mongod on 这个命令貌似过时了 安装后自带开机启动 无需设置

设置程序监听IP

vim /etc/mongod.conf 设置bindIp: 0.0.0.0 使其监听全IPv4,我们可以通过windows上运行图形化工具访问Linux上的数据库

运行状态确认

service mongod status 默认端口为27017 数据保存地址:/var/lib/mongo/ 日志保存地址:/var/log/mongodb/mongod.log 用户名:mongod 配置文件:/etc/mongod.conf -------停止MongoDB service mongod stop -------重启MongoDB service mongod restart

使用MongoDB本地管理工具

-------本地连接至MongoDB 使用默认IP和默认端口 mongo 输入help弹出命令支持菜单 进入本界面后,输入行的左端变成了"> ",退出界面输入"exit"回车

查询所有数据库

show dbs

显示当前数据库

db

创建/切换数据库

use Sekia

删除数据库

db.dropDatabase()

查询数据库状态

db.stats()

"db" : "Sekia",
"collections" : 0,
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"fsUsedSize" : 0,
"fsTotalSize" : 0,
"ok" : 1

创建集合

db.createCollection(“collName”, {size: 20, capped: 5, max: 100});

查询所有集合

db.getCollectionNames() 在Linux环境下使用本地工具只是简单了解一下,图形工具更便于管理些.

图形工具访问数据库

可以搜索下"mongodb best GUI Client"这样的关键词,能用的工具挺多的. 这里使用MongoDB Compass,官网下载地址. 我这里选择下载1.15.1社区稳定版的Windows64位zip压缩包. 运行程序后,需要输入连接信息,这里使用SSH隧道登陆. SSH Tunnel:Use Password SSH Hostname:服务器外网IP SSH Tunnel Port:服务器SSH端口,默认为22,我个人使用的是4000 SSH Username:服务器用户名,可以使用root账户登陆 SSH Password:对应密码 连接成功后:

C#程序支持

图形工具远程连接成功后,可以在界面上随便捣腾一下,但是对于新手来说过于缺乏目标. 而且我们最终会在.NET Core平台上,使用C#程序去读写数据库,图形化工具主要用来整体观察 接下来就是在VS中操作了

安装MongoDB的C#版驱动

这里我们参考MongoDB的C#驱动说明页. 在安装方式中,官方提供2种方式,Nuget安装(Nuget Installation)和编译安装(Binary Installation),并推荐使用Nuget. 在版本支持列表中可以看到,最新版本Version 2.7匹配的是MongoDB 4.0/.NET 4.5-4.6/.NET Core 1.0-2.0 编译环境为Visual Studio 2017

Nuget安装

使用Nuget是最简单的安装驱动方式,一共有5个包可以在nuget上获得,其中MongoDB.Driver是我们需要的. MongoDB.Driver:新驱动,在新项目中使用. MongoDB.Driver.Core:驱动的核心,MongoDB.Driver的依赖之一,你可能不会直接用上这个包. MongoDB.Driver.Bson:MongoDB.Driver的依赖之一.Bson是Binary JSON的简称,是一种类Json的二进制存储格式,使用于存储数据和网络数据交换. 新建工程Nugettest,在"管理Nuget程序包"中搜索MongoDB.Driver,我这边看到的是第一个包就是V2.7.0的MongoDB.Driver,安装它. 在项目mongodbtest的依赖项中可以看到新增的Nuget目录中有了MongoDB.Driver和它的依赖.

编译安装

先下载源码,地址在github. 下载最新版源码包,解压后是一个很大的工程包,先运行CSharpDriver.sln编译一下确认没有问题. 将驱动加入其它项目的话只需要复制其中部分文件夹到新的工程文件夹即可: MongoDB.Driver MongoDB.Driver.Dotnet MongoDB.Bson MongoDB.Bson.Dotnet MongoDB.Driver.Core MongoDB.Driver.Core.Dotnet MongoDB.Shared 新建工程Binarytest将其中3个以.Dotnet结尾的工程添加进去,编译以下确认没有问题. 在项目的.csproj文件中加入以下内容可以设置输出目录和禁止在输出目录生成额外文件夹.

  <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<!-- 禁止在输出目录生成额外文件夹 -->
<!-- https://docs.mongodb.com/ecosystem/drivers/csharp/ -->
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)$(Platform)'=='ReleaseAnyCPU'">
<OutputPath>..\..\..\Bin\</OutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)$(Platform)'=='DebugAnyCPU'">
<OutputPath>..\..\..\Bin\</OutputPath>
</PropertyGroup>

要在我们自己的项目中使用编译安装的驱动,为项目添加"引用",并选择MongoDB.Driver.Dotnet即可.

MongoDB的C#入门程序

2种安装方式都能引用到MongoDB.Driver库,选一种即可,接下来写程序的步骤没有差别.

using System;
using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver.Linq;
using System.Linq;

namespace mongodbtest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");

//连接到本地MongoDB服务
var client = new MongoClient();
//var client = new MongoClient("mongodb://localhost:27017");
//client实例将在数据库间建立一个连接池

//卸载指定数据库
client.DropDatabase("foo");
Console.WriteLine("删除了数据库foo");

//建立一个Database
var database = client.GetDatabase("foo");
Console.WriteLine("创建了数据库foo");
//使用client的GetDatabase方法获取指定名称的数据库
//如果指定数据库不存在 则创建该数据库

//创建一个Collection
var collection = database.GetCollection<BsonDocument>("bar");
//如果指定Collection不存在 则创建该集合
//collection对应在数据库foo中的bar集合

//创建一个BsonDocument
var documentNew = new BsonDocument
{
{"name","MongoDB" },
{"type","Datebase" },
{"count",1 },
{"info",new BsonDocument
{
{"x",203 },
{"y",102 }
}
}
};

//将一个BsonDocument插入到一个集合中
collection.InsertOne(documentNew);
//可以使用异步方法InsertOneAsync()
//await collection.InsertOneAsync(document);
//提示await运算符只能用于异步方法中:为所在方法添加修饰符async
//static void Main(string[] args) 入口方法不能加入async
//驱动中包含丰富的异步特性
//所有的方法都包括同步和异步版本

//创建12个BsonDocument 并插入
var documentsNew = Enumerable.Range(2, 12).Select(i => new BsonDocument("counter", i));
collection.InsertMany(documentsNew);
//await collection.InsertManyAsync(documents);

//计算Document数量
var count = collection.CountDocuments(new BsonDocument());
Console.WriteLine("文档数为"+count);
//var countAsync = await collection.CountDocumentsAsync(new BsonDocument());
//new BsonDocument() 作为CountDocumentsAsync方法的filter(过滤器)
//在本例中使用空的BsonDocument来计算全部文档

//查询(Query)集合
//使用Find方法查询集合
//Find方法返回一个IFindFlunt<TDocument,TProjection>实例
//该实例提供一个流接口,用于把查询操作链接起来

//找到集合中的第一个文档
//返回第一个文档或者null
var documentFind = collection.Find(new BsonDocument()).FirstOrDefault();
//Console.WriteLine(documentFind.ToString());
//var documentFindAsync = await collection.Find(new BsonDocument()).FirstOrDefaultAsync();
//Console.WriteLine(documentFindAsync.ToString());
//本例中应返回以下文档:
//{ "_id" : ObjectId("5b8e6603adaf4c1b7808e1bb"), "name" : "MongoDB", "type" : "Datebase", "count" : 1, "info" : { "x" : 203, "y" : 102 } }
//在图形工具中也可以同步查看
//"id"元素被自动添加
//以"_"和"$"开头的名称为MongoDB内部使用

//找到集合中的全部文档
var documentsAll = collection.Find(new BsonDocument()).ToList();
//var documentsAllAsync = await collection.Find(new BsonDocument()).ToListAsync();
//如果文档数量不大的话可以使用本方法 将返回一个文档列表
//如果文档数量相当大,可以使用ForEachAsync方法,每返回一个文档打印一条消息
//await collection.Find(new BsonDocument()).ForEachAsync(d => Console.WriteLine(d));
//使用同步方法读取每一个文档
var cursor = collection.Find(new BsonDocument()).ToCursor();
foreach(var doc in cursor.ToEnumerable())
{
Console.WriteLine("打印全部"+doc);
}
//会将从第1个到第13个文档一次打印一遍

//使用Filter获得单个文件
//创建一个过滤器并传递给Find方法来获得一个collection的子集
//下面的例子将返回查找到的字段counter值为7的第一个文档
var filter1 = Builders<BsonDocument>.Filter.Eq("counter", 7);
var document1 = collection.Find(filter1).First();
Console.WriteLine("打印7号"+document1);
//FirstAsyc()

//使用Filter获得一堆文档
//如果我们想得到所有counter>10的文档:
var filter2 = Builders<BsonDocument>.Filter.Gt("counter", 10);
var cursor2 = collection.Find(filter2).ToCursor();
foreach(var doc in cursor2.ToEnumerable())
{
Console.WriteLine("打印大于10"+doc);
}
//ForEachAsync()

//我们也可以设置一个范围,如5<counter<=8
var filterBuilder = Builders<BsonDocument>.Filter;
var filter3 = filterBuilder.Gt("counter", 5) & filterBuilder.Lte("counter", 8);
var cursor3 = collection.Find(filter3).ToCursor();
foreach(var doc in cursor3.ToEnumerable())
{
Console.WriteLine("打印范围内"+doc);
}

//整理文档
//可以使用Sort方法添加一个排序用来查找.
//下面的例子使用了Exists过滤器,和Descending排序方法来整理文档
var filter4 = Builders<BsonDocument>.Filter.Exists("counter");
var sort = Builders<BsonDocument>.Sort.Descending("counter");
var document4 = collection.Find(filter4).Sort(sort).First();
Console.WriteLine("降序第一" + document4);

//获取指定字段
//我们通常并不需要文档的全部数据,而是只需要其中的某些字段
//使用Projection为查找操作创建prpjection元素
//下面的例子将输出首个文档,用Exclud方法不显示文档的_id字段
var projection1 = Builders<BsonDocument>.Projection.Exclude("_id");
var document5 = collection.Find(new BsonDocument()).Project(projection1).First();
Console.WriteLine("不显示_id字段" + document5);

var projection2 = Builders<BsonDocument>.Projection.Include("count");
document5 = collection.Find(new BsonDocument()).Project(projection2).First();
Console.WriteLine("只显示count字段" + document5);

var projection3 = Builders<BsonDocument>.Projection.Include("counter");
document5 = collection.Find(new BsonDocument()).Project(projection3).First();
Console.WriteLine("只显示counter字段" + document5);

//修改文档
//下面的例子将修改第一个匹配到的,符合counter==10的文档,并设置i值为110;
var filter6 = Builders<BsonDocument>.Filter.Eq("counter", 10);
var update6 = Builders<BsonDocument>.Update.Set("counter", 110);
collection.UpdateOne(filter6, update6);
//批量修改文档只需使用UpdateMany/UpdateManyAsync

//查找counter<4的字段,使counter=counter+100
var filter7 = Builders<BsonDocument>.Filter.Lt("counter", 4);
var update7 = Builders<BsonDocument>.Update.Inc("counter", 100);
var result = collection.UpdateMany(filter7, update7);
if(result.IsModifiedCountAvailable)
{
Console.WriteLine("成功修改条数"+result.ModifiedCount);
}
//UpdateResult提供update的结果,包括被修改的文档数

cursor = collection.Find(new BsonDocument()).ToCursor();
foreach (var doc in cursor.ToEnumerable())
{
Console.WriteLine("打印全部" + doc);
}


//删除文档
//删除一个文档
var filter8 = Builders<BsonDocument>.Filter.Eq("counter", 7);
collection.DeleteOne(filter8);
//使用DeleteMany删除多个文档
var filter9 = Builders<BsonDocument>.Filter.Gte("counter", 5);
var result9 = collection.DeleteMany(filter9);
Console.WriteLine("删除了的条数:"+result9.DeletedCount);
//DeleteResult提供关于操作的信息,包括被删除文档数

cursor = collection.Find(new BsonDocument()).ToCursor();
foreach (var doc in cursor.ToEnumerable())
{
Console.WriteLine("批量删除后还剩" + doc);
}

//区块写
//有两种bulk operation
//1.有序区块操作
//2.无序区块操作
var models = new WriteModel<BsonDocument>[]
{
new InsertOneModel<BsonDocument>(new BsonDocument("_id",1)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id",2)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id",3)),
new UpdateOneModel<BsonDocument>(
new BsonDocument("_id",1),
new BsonDocument("$set",new BsonDocument("x",2))),
new DeleteOneModel<BsonDocument>(new BsonDocument("_id",3)),
new ReplaceOneModel<BsonDocument>(
new BsonDocument("_id",3),
new BsonDocument("_id",3).Add("x",4))
};

//1.有序区块操作实例,操作顺序是保障的
collection.BulkWrite(models);

//2.无序区块操作实例,没有保障操作顺序
//这里我其实没有看懂,可以做修改测试如连续修改某个值10次,看操作顺序对结果的影响
//collection.BulkWrite(models, new BulkWriteOptions { IsOrdered = false });

cursor = collection.Find(new BsonDocument()).ToCursor();
foreach (var doc in cursor.ToEnumerable())
{
Console.WriteLine("最终结果" + doc);
}
}
}
}

运行结果

导出导入

这里参考关于导入和导出的官方文档. MongoDB的导出支持将数据保存为JSON或CSV,使用系统自带的命令行: mongoexport --db foo --collection bar --out bar.json bar.json会出现在命令行当前位置 mongoimport需要使用mongoexport导出的文件 mongoimport --db foo --collection bar --file bar.json 这个应该是需要不少时间深入学习的,毕竟那么多的API. 今天的学习就到这里,下一篇将在游戏demo中使用到MongoDB.