如何在.Net中使用MongoDB

  最近在研究mongodb,针对.net 中使用mongodb的文章要么是早期的驱动版本,要么资料很少,所以写个随笔记录一下

什么是MongoDB

  MongoDB是基于文档的存储的(而非表),是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。Mongo主要解决的是海量数据的访问效率问题。因为Mongo主要是支持海量数据存储的,所以Mongo还自带了一个出色的分布式文件系统GridFS,可以支持海量的数据存储。由于Mongo可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎。

  BSON是MongoDB的数据存储格式。大家对于JSON比较熟悉,但是什么是BSON呢BSON基于JSON格式,选择JSON进行改造的原因主要是JSON的通用性及JSON的schemaless的特性。BSON具有如下特点

  1.更快的遍历速度

  对JSON格式来说,太大的JSON结构会导致数据遍历非常慢。在JSON中,要跳过一个文档进行数据读取,需要对此文档进行扫描才行,需要进行麻烦数据结构匹配,比如括号的匹配,而BSON对JSON的一大改进就是,它会将JSON的每一个元素的长度存在元素的头部,这样你只需要读取到元素长度就能直接seek到指定的点上进行读取了。

  2.操作更简易

  对JSON来说,数据存储是无类型的,比如你要修改基本一个值,从9到10,由于从一个字符变成了两个,所以可能其后面的所有内容都需要往后移一位才可以。而使用BSON,你可以指定这个列为数字列,那么无论数字从9长到10还是100,我们都只是在存储数字的那一位上进行修改,不会导致数据总长变大。当然,在MongoDB中,如果数字从整形增大到长整型,还是会导致数据总长变大的。

  3.增加了额外的数据类型

  JSON是一个很方便的数据交换格式,但是其类型比较有限。BSON在其基础上增加了“byte array”数据类型。这使得二进制的存储不再需要先base64转换后再存成JSON。大大减少了计算开销和数据大小。当然,在有的时候,BSON相对JSON来说也并没有空间上的优势,因为有了类型概念。

MongoDB windows下 安装

  MongoDB的安装很简单,设置好安装路径后,一直Next直到安装结束,最大的坑就是MongoDB服务的安装,下面具体说下MongoDB安装之后的一些配置操作

  1.在根目录下创建数据库路径(data目录)、日志路径(logs目录)、日志文件(mongo.log文件)、配置路径(conf目录)我的安装路径是:D:\Program Files\mongodb

  2.在conf目录下创建配置文件mongo.conf,文件内容如下:

    logpath=D:\Program Files\mongodb\logs\mongodb.log #日志输出文件路径
logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
journal=true #启用日志文件,默认启用
quiet=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
port=27017 #端口号 默认为27017
auth=true #启用验证 需要用户名密码

  配置完成以上2个步骤 就可以 启动MongoDB了

  运行CMD 输入命令 (注意 mongod的路径)

    mongod --config " D:\Program Files\mongodb\data \conf\mongo.conf"

  3.创建并启动MongoDB服务

  如果每次都按照步骤三那样操作,岂不是相当麻烦,按照如下命令来创建并启动MongoDB服务,就可以通过windows服务来管理MongoDB的启动和关闭了

    mongod --config " D:\Program Files\mongodb\data \conf\mongo.conf"  --install --serviceName "MongoDB"
net start MongoDB

  测试是否成功 可以在 浏览器中输入http://localhost:27017/如果出现下图表示服务安装成功

  如果需要卸载MongoDB服务 在CMD 中运行

    mongod.exe --remove --serviceName "MongoDB"

  前期准备工作完成了,就可以开始撸代码了

如何在.net 中使用MongoDB

  首先在项目中引入 MongoDB.Bson.dll,MongoDB.Driver.dll,MongoDB.Driver.Core.dll 我使用的是2.0版本的 现在好多文章都是介绍使用1+版本的 这也是我写此文的目的引入驱动DLL后,就可以开始撸代码了

部分代码如下

        private static MongoClient client;
private static IMongoDatabase database;
//本地配置
private const string MongoDBConnectionStr = "mongodb://localhost";
//数据库名称
private static string DefaultDataBaseName = "Test"; public MongoDBHelper()
{
GetConnection(DefaultDataBaseName);
} /// <summary>
/// 构造函数 指定数据库
/// </summary>
/// <param name="dataBaseName"></param>
public MongoDBHelper(string dataBaseName)
{
GetConnection(dataBaseName);
} private static void GetConnection(string dataBaseName)
{
client = new MongoClient(MongoDBConnectionStr);
database = client.GetDatabase(dataBaseName);
} /// <summary>
/// 异步插入一条数据,手动输入collection name
/// </summary>
public Task InsertAsync<T>(string collectionName, T obj)
{
if (database == null)
{
throw new Exception("没有指定数据库");
}
var collection = database.GetCollection<T>(collectionName);
return collection.InsertOneAsync(obj);
} /// <summary>
/// 异步插入一条数据,采用类型T的完全限定名作为collection name
/// </summary>
public Task InsertAsync<T>(T obj)
{
return InsertAsync(typeof(T).FullName, obj);
} /// <summary>
/// 异步插入多条数据,手动输入collection name
/// </summary>
public Task BatchInsertAsync<T>(string collectionName, IEnumerable<T> objs)
{
if (database == null)
{
throw new Exception("没有指定数据库");
}
if (objs == null)
{
throw new ArgumentException();
}
var collection = database.GetCollection<T>(collectionName);
return collection.InsertManyAsync(objs);
} /// <summary>
/// 异步插入多条数据,采用类型T的完全限定名作为collection name
/// </summary>
public Task BatchInsertAsync<T>(IEnumerable<T> objs)
{
return BatchInsertAsync(typeof(T).FullName, objs);
} /// <summary>
/// 插入一条数据
/// </summary>
public void Insert<T>(T obj)
{
InsertAsync(obj).Wait();
} /// <summary>
/// 插入多条数据
/// </summary>
public void Insert<T>(IEnumerable<T> objs)
{
BatchInsertAsync(objs).Wait();
} /// <summary>
/// MongoDB C# Driver的Find方法,返回IFindFluent。手动输入collection name
/// </summary>
public IFindFluent<T, T> Find<T>(string collectionName, FilterDefinition<T> filter, FindOptions options = null)
{
if (database == null)
{
throw new Exception("没有指定数据库");
}
var collection = database.GetCollection<T>(collectionName);
return collection.Find(filter, options);
} /// <summary>
/// MongoDB C# Driver的Find方法,返回IFindFluent。采用类型T的完全限定名作为collection name
/// </summary>
public IFindFluent<T, T> Find<T>(FilterDefinition<T> filter, FindOptions options = null)
{
return Find(typeof(T).FullName, filter, options);
} /// <summary>
/// 取符合条件的数据 sort中多个排序条件逗号分隔,默认asc
/// </summary>
public List<T> Get<T>(Expression<Func<T, bool>> condition, int skip, int limit, string sort)
{
return Get(new List<Expression<Func<T, bool>>> { condition }, skip, limit, sort);
} public List<T> Get<T>(Expression<Func<T, bool>> condition)
{
return Get(condition, 0, 0, null);
} /// <summary>
/// 取符合条件的数据 sort中多个排序条件逗号分隔,默认asc
/// </summary>
public List<T> Get<T>(List<Expression<Func<T, bool>>> conditions, int skip, int limit, string sort)
{
if (conditions == null || conditions.Count == 0)
{
conditions = new List<Expression<Func<T, bool>>> { x => true };
}
var builder = Builders<T>.Filter;
var filter = builder.And(conditions.Select(x => builder.Where(x))); var ret = new List<T>();
try
{
List<SortDefinition<T>> sortDefList = new List<SortDefinition<T>>();
if (sort != null)
{
var sortList = sort.Split(',');
for (var i = 0; i < sortList.Length; i++)
{
var sl = Regex.Replace(sortList[i].Trim(), @"\s+", " ").Split(' ');
if (sl.Length == 1 || (sl.Length >= 2 && sl[1].ToLower() == "asc"))
{
sortDefList.Add(Builders<T>.Sort.Ascending(sl[0]));
}
else if (sl.Length >= 2 && sl[1].ToLower() == "desc")
{
sortDefList.Add(Builders<T>.Sort.Descending(sl[0]));
}
}
}
var sortDef = Builders<T>.Sort.Combine(sortDefList);
ret = Find(filter).Sort(sortDef).Skip(skip).Limit(limit).ToListAsync().Result;
}
catch (Exception e)
{
//异常处理
}
return ret;
} public List<T> Get<T>(List<Expression<Func<T, bool>>> conditions)
{
return Get(conditions, 0, 0, null);
}

  示例代码中只实现了插入和查询功能,后续会将完整代码上传

  本文只记录了MongoDB的最基本使用,后续会介绍副本级,主从自动备份等机制与实现方式

如何在.Net中使用MongoDB的更多相关文章

  1. 如何在cmd中启动MongoDB服务器和客户端

    1 先将MongoDB的bin路径添加到环境变量中 2 打开cmd输入mongod 开启MongoDB服务器 3 输入mongo开启MongoDB客户端

  2. 如何在linux中部署mongodb并设置连接认证

    在windows上给mongodb设置连接认证权限:mongodb默认是不认证的,默认没有账号,现在就讲讲怎么设置账户和密码 1.首先进入C:\mongodb\bin下面双击运行mongo.exe启动 ...

  3. 在Python应用中使用MongoDB

    Python是开发社区中用于许多不同类型应用的强大编程语言.很多人都知道它是可以处理几乎任何任务的灵活语言.因此,在Python应用中需要一个什么样的与语言本身一样灵活的数据库呢?那就是NoSQL,比 ...

  4. 在Windows操作系统中安装MongoDB

    如何在Windows操作系统中安装MongoDB: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/ 启动Mon ...

  5. 在.NET Core中使用MongoDB明细教程(1):驱动基础及文档插入

    MongoDB,被归类为NoSQL数据库,是一个以类JSON格式存储数据的面向文档的数据库系统.MongoDB在底层以名为bson的二进制编码格式表示JSON文档,MongoDB bson实现是轻量级 ...

  6. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  7. 如何在SpringBoot中使用JSP ?但强烈不推荐,果断改Themeleaf吧

    做WEB项目,一定都用过JSP这个大牌.Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的.当你从一个传统的Spring MVC项目转入一个Spring Boot ...

  8. 如何在latex 中插入EPS格式图片

    如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...

  9. 如何正确的使用json?如何在.Net中使用json?

    什么是json json是一种轻量级的数据交换格式,由N组键值对组成的字符串,完全独立于语言的文本格式. 为什么要使用json 在很久很久以前,调用第三方API时,我们通常是采用xml进行数据交互,但 ...

随机推荐

  1. VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)

    一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...

  2. Angular--学习

    18:28:34 Angular简介 AngularJS通过指令 扩展了HTML,并通过 表达式 绑定数据到HTML Angular扩展了HTML AngularJS 通过 ng-directives ...

  3. 看Lucene源码必须知道的基本概念

    终于有时间总结点Lucene,虽然是大周末的,已经感觉是对自己的奖励,毕竟只是喜欢,现在的工作中用不到的.自己看源码比较快,看英文原著的技术书也很快.都和语言有很大关系.虽然咱的技术不敢说是部门第一的 ...

  4. Masonry适配的简单使用

    一.Masonry是什么: 答:是一个很好的三方,用来做适配的 二.怎么使用Masonry 1.先导入头文件 #define MAS_SHORTHAND #define MAS_SHORTHAND_G ...

  5. iOS 检测文本中的 URL、电话号码等信息

    iOS 检测文本中的 URL.电话号码等信息 要检测文本中的 URL.电话号码等,除了用正则表达式,还可以用 NSDataDetector. 用 NSTextCheckingResult.Checki ...

  6. stick footer布局

    需求: 将footer固定到底部.文章内容不足满屏时 footer在底部,超过满屏时footer在内容末尾. 方法一: <div id="wrap"> <div ...

  7. 网站启用gzip压缩

    gzip压缩启用不启用还是要看实际情况的,启用gzip后可以相应的减轻带宽压力但是同时也会增加cpu的压力(压缩解压),相反的如果不启用那么cpu压力也会相应的减少,具体情况具体分析. Linux开启 ...

  8. Swift中枚举的总结以及使用

    枚举定义了一组具有相关性的数据,是开发者可以再带吗中以一个安全的方式来使用这些值,以又助于提供代码的可读性. 在Swift中,枚举可以分成两种:任意类型的枚举和指定类型的枚举,结构如下: //任意类型 ...

  9. kafka集群中常见错误的解决方法:kafka.common.KafkaException: Should not set log end offset on partition

    问题描述:kafka单台机器做集群操作是没有问题的,如果分布多台机器并且partitions或者备份的个数大于1都会报kafka.common.KafkaException: Should not s ...

  10. vue学习笔记-one

    学习vue基础以来,看各种教程,练习,随手写写,有错误请大家指导, 目前vue已经升级到2.0的版本,学习也最好是2.0的版本开始. 先看vue的几个特点:1,简单,2,轻量,3,模块友好 4, 组件 ...