windows7下使用MongoDB实现仓储设计
简单的介绍一下,我使用MongoDB的场景。
我们现在的物联网环境下,有部分数据,采样频率为2000条记录/分钟,这样下来一天24*60*2000=2880000约等于300万条数据,以后必然还会增加。之前数据库使用的是mssql,对于数据库的压力很大,同时又需要保证历史查询的响应速度,这种情况下,在单表中数据量大,同时存在读写操作。不得已采用MongoDB来存储数据。如果使用MongoDB,则至少需要三台机器,两台实现读写分离,一台作为仲裁(当然条件不允许也可以不用),每台机器的内存暂时配置在16G,公司小,没办法,据说,使用这个MongoDB需要机器内存最少92G,我没有验证过,但是吃内存是公认的,所以内存绝对要保证,就算保证了,也不一定完全就没有意外发生。我们上面的这些特殊的数据是允许少量的丢失的,这些只是做分析使用的,几个月了,暂时还没出现数据丢失的情况,可能最新版本早就修复了吧,新手使用建议多看下官网上的说明。下面直接奔入主题:
一、安装部署和配置环境
1.安装部署mongo-server(V3.4)
参考点击这里进入
这个时候不要启动,接着配置config文件
2.配置Config文件
dbpath=C:/ProgramFiles/MongoDB/Server/3.4/bin/data/db logpath=C:/ProgramFiles/MongoDB/Server/3.4/bin/data/log/master.log pidfilepath=C:/ProgramFiles/MongoDB/Server/3.4/bin/master.pid directoryperdb=true logappend=true replSet=testrs bind_ip=10.1.5.25 port=27016 oplogSize=10000 noauth=true storageEngine=wiredTiger wiredTigerCacheSizeGB=2 syncdelay=30 wiredTigerCollectionBlockCompressor=snappy
以上是详细的配置参数,其中路径部分根据需要更改,这里设置的oplogsize大小为10G,根据业务场景进行调整,另外auth权限为null,因为设置权限会增加服务开销,影响效率,最下面几行是内存引擎,可以控制副本集同步及内存限制,防止内存泄露。
3.启动mongo-server
4.添加副本集配置
conf= { "_id":"testrs", "members":[ {"_id":0,"host":"10.1.5.25:27016"}, {"_id":1,"host":"10.1.5.26:27016"}, {"_id":2,"host":"10.1.5.27:27016"} ] } rs.initiate(conf)
此时副本集集群配置已经完成,然后在命令行中输入:rs.status(),查看副本集状态,需要查看同步情况,可以输入命令:db.serverStatus().
5.设置副本集可读写
Rs.slaveOk()
6..NET操作mongo
连接设置,请参考个人封装Unitoon.Mongo代码所示。
7.性能对比
读写速度:Redis>Mongo>Mssqlserver
可容纳数据量:Mssqlserver~Mongo>Redis
存储数据类型:Mongo>Mssqlserver>Redis
Note:内存持续上升,内部没有内存回收机制,若限制内存,则可能出现查询速度变慢,数据丢失等问题,建议优化查询效率,建立索引
Db.test.ensureIndex({"username":1,"age":-1})
强制释放内存命令:db.runCommand({closeAllDatabases:1})
二、仓储设计
1.基类BaseEntity
namespaceUnitoonIot.Mongo { //////实体基类,方便生成ObjId /// [Serializable] [ProtoContract(ImplicitFields=ImplicitFields.AllPublic)] //[ProtoInclude(10,typeof(NormalHistory))] publicclassBaseEntity { //[BsonRepresentation(BsonType.ObjectId)] publicObjectIdId{get;set;} //////数据库名称 /// publicstringDbName{get;set;} //////给对象初值 /// publicBaseEntity() { //this.ObjId=ObjectId.GenerateNewId().ToString(); //this.Id=ObjectId.NewObjectId().ToString(); } } }
这里需要注意时间格式,MongoDB默认时间格式为国际时间,所以在写入数据时和读取数据时,时间格式要一致,此例中没有对时间进行特殊处理,由传入的时间格式确定。
2.Repository继承接口IMongoRepository
namespaceUnitoonIot.Mongo { publicinterfaceIMongoRepositorywhereTEntity:class { } }
3.MongoRepository
usingMongoDB.Driver; usingMongoDB.Bson; usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Linq.Expressions; usingSystem.Text; usingSystem.Threading.Tasks; usingMongoDB.Bson.Serialization.Attributes; usingMongoDB.Driver.Linq; usingSystem.Configuration; usingSystem.IO; usingUnitoonIot.AppSetting; namespaceUnitoonIot.Mongo { publicclassMongoDb { privatestaticstringConnectionStringHost; privatestaticstringUserName; privatestaticstringPassword; privatestaticIMongoDatabase_db=null; privatestaticreadonlyobjectLockHelper=newobject(); //////mongodb初始化 /// publicstaticvoidInit() { ConnectionStringHost="10.1.5.24:27016,10.1.5.24:27016,10.1.5.26:27017"; //AppSettings.GetConfigValue("MongoHost");//"10.1.5.24:27016"; UserName=AppSettings.GetConfigValue("MongoUserName"); Password=AppSettings.GetConfigValue("MongoPwd"); } staticMongoDb() { } publicstaticIMongoDatabaseGetDb(stringdbName,stringoptions=null) { if(_db!=null)return_db; lock(LockHelper) { if(_db!=null)return_db; vardatabase=dbName; varuserName=UserName; varpassword=Password; varauthentication=string.Empty; varhost=string.Empty; if(!string.IsNullOrWhiteSpace(userName)) { authentication=string.Concat(userName,':',password,'@'); } if(!string.IsNullOrEmpty(options)&&!options.StartsWith("?")) { options=string.Concat('?',options); } host=string.IsNullOrEmpty(ConnectionStringHost)?"localhost":ConnectionStringHost; database=database??"testdb"; //mongodb://[username:password@]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/[database][?options]] varconString=options!=null?$"mongodb://{authentication}{host}/{database}{options}" :$"mongodb://{authentication}{host}/{database}"; varurl=newMongoUrl(conString); varmcs=MongoClientSettings.FromUrl(url); mcs.MaxConnectionLifeTime=TimeSpan.FromMilliseconds(1000); varclient=newMongoClient(mcs); _db=client.GetDatabase(url.DatabaseName); } return_db; } } //////MongoDb数据库操作类 /// publicclassMongoRepository:IMongoRepository whereT:BaseEntity { #regionreadonlyfield /// ///表名 /// privatereadonlyIMongoCollection_collection=null; /// ///数据库对象 /// privatereadonlyIMongoDatabase_database; #endregion //////构造函数 /// publicMongoRepository() { this._database=MongoDb.GetDb(Activator.CreateInstance().DbName,"readPreference=secondaryPreferred");//primaryPreferred/secondaryPreferred/nearest _collection=_database.GetCollection (typeof(T).Name); } #region增加 /// ///插入对象 /// ///插入的对象 publicvirtualTInsert(Tt) { //varflag=ObjectId.GenerateNewId(); //t.GetType().GetProperty("Id").SetValue(t,flag); //t.Time=DateTime.Now; _collection.InsertOne(t); returnt; } /// ///批量插入 /// ///要插入的对象集合 publicvirtualIEnumerable InsertBatch(IEnumerable ts) { _collection.InsertMany(ts); returnts; } /// ///插入对象 /// ///插入的对象 publicvirtualvoidInsertAsync(Tt) { //varflag=ObjectId.GenerateNewId(); //t.GetType().GetProperty("Id").SetValue(t,flag); //t.Time=DateTime.Now; _collection.InsertOneAsync(t); } /// ///批量插入 /// ///要插入的对象集合 publicvirtualvoidInsertBatchAsync(IEnumerable ts) { _collection.InsertManyAsync(ts); } #endregion #region删除 /// ///删除 /// ///publicvirtuallongDelete(Tt) { varfilter=Builders .Filter.Eq("Id",t.Id); varresult=_collection.DeleteOne(filter); returnresult.DeletedCount; } /// ///删除 /// ///publicvirtualvoidDeleteAsync(Tt) { varfilter=Builders .Filter.Eq("Id",t.Id); _collection.DeleteOneAsync(filter); } /// ///按条件表达式删除 /// ///条件表达式 /// publicvirtuallongDelete(Expression >predicate) { varresult=_collection.DeleteOne(predicate); returnresult.DeletedCount; } /// ///按条件表达式删除 /// ///条件表达式 /// publicvirtualvoidDeleteAsync(Expression >predicate) { _collection.DeleteOneAsync(predicate); } /// ///按条件表达式批量删除 /// ///条件表达式 /// publicvirtuallongDeleteBatch(Expression >predicate) { varresult=_collection.DeleteMany(predicate); returnresult.DeletedCount; } /// ///按条件表达式批量删除 /// ///条件表达式 /// publicvirtualvoidDeleteBatchAsync(Expression >predicate) { _collection.DeleteManyAsync(predicate); } /// ///按检索条件删除 ///建议用Builders ///构建复杂的查询条件 /// 条件 /// publicvirtuallongDelete(FilterDefinition filter) { varresult=_collection.DeleteOne(filter); returnresult.DeletedCount; } /// ///按检索条件删除 ///建议用Builders ///构建复杂的查询条件 /// 条件 /// publicvirtualvoidDeleteAsync(FilterDefinition filter) { _collection.DeleteOneAsync(filter); } #endregion #region修改 /// ///修改(Id不变) /// ///publicvirtuallongUpdate(Tt) { varfilterBuilder=Builders .Filter; varfilter=filterBuilder.Eq("Id",t.Id); varupdate=_collection.ReplaceOne(filter,t,newUpdateOptions(){IsUpsert=true}); returnupdate.ModifiedCount; } /// ///修改(Id不变) /// ///publicvirtualvoidUpdateAsync(Tt) { varfilterBuilder=Builders .Filter; varfilter=filterBuilder.Eq("Id",t.Id); _collection.ReplaceOneAsync(filter,t,newUpdateOptions(){IsUpsert=true}); } /// ///用新对象替换新文档 /// ///查询条件 /// 对象 /// 修改影响文档数 publicvirtuallongUpdate(Expression>filter,Tt) { varupdate=_collection.ReplaceOne(filter,t,newUpdateOptions(){IsUpsert=true}); returnupdate.ModifiedCount; } /// ///用新对象替换新文档 /// ///查询条件 /// 对象 /// 修改影响文档数 publicvirtuallongUpdate(FilterDefinitionfilter,Tt) { varupdate=_collection.ReplaceOne(filter,t,newUpdateOptions(){IsUpsert=true}); returnupdate.ModifiedCount; } /// ///用新对象替换新文档 /// ///查询条件 /// 对象 /// 修改影响文档数 publicvirtualvoidUpdateAsync(Expression>filter,Tt) { _collection.ReplaceOneAsync(filter,t,newUpdateOptions(){IsUpsert=true}); } /// ///用新对象替换新文档 /// ///查询条件 /// 对象 /// 修改影响文档数 publicvirtualvoidUpdateAsync(FilterDefinitionfilter,Tt) { _collection.ReplaceOneAsync(filter,t,newUpdateOptions(){IsUpsert=true}); } /// ///根据Id和条件文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 对象Id /// 修改影响文档数 publicvirtuallongUpdate(stringid,UpdateDefinitionupdate) { varfilterBuilder=Builders .Filter; varfilter=filterBuilder.Eq("Id",newObjectId(id)); varresult=_collection.UpdateOne(filter,update,newUpdateOptions(){IsUpsert=true}); returnresult.ModifiedCount; } /// ///根据Id和条件文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 对象Id /// 修改影响文档数 publicvirtualvoidUpdateAsync(stringid,UpdateDefinitionupdate) { varfilterBuilder=Builders .Filter; varfilter=filterBuilder.Eq("Id",newObjectId(id)); _collection.UpdateOneAsync(filter,update,newUpdateOptions(){IsUpsert=true}); } /// ///根据条件修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtualvoidUpdate(UpdateDefinitionupdate,Expression >filter) { _collection.UpdateOne(filter,update,newUpdateOptions(){IsUpsert=true}); } /// ///根据条件修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtuallongUpdate(UpdateDefinitionupdate,FilterDefinition filter) { varresult=_collection.UpdateOne(filter,update,newUpdateOptions(){IsUpsert=true}); returnresult.ModifiedCount; } /// ///根据条件修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtualvoidUpdateAsync(UpdateDefinitionupdate,Expression >filter) { _collection.UpdateOneAsync(filter,update,newUpdateOptions(){IsUpsert=true}); } /// ///根据条件修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtualvoidUpdateAsync(UpdateDefinitionupdate,FilterDefinition filter) { _collection.UpdateOneAsync(filter,update,newUpdateOptions(){IsUpsert=true}); } /// ///根据条件批量修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtuallongUpdateBatch(UpdateDefinitionupdate,Expression >filter) { varresult=_collection.UpdateMany(filter,update,newUpdateOptions(){IsUpsert=true}); returnresult.ModifiedCount; } /// ///根据条件批量修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtuallongUpdateBatch(UpdateDefinitionupdate,FilterDefinition filter) { varresult=_collection.UpdateMany(filter,update,newUpdateOptions(){IsUpsert=true}); returnresult.ModifiedCount; } /// ///根据条件批量修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtualvoidUpdateBatchAsync(UpdateDefinitionupdate,Expression >filter) { _collection.UpdateManyAsync(filter,update,newUpdateOptions(){IsUpsert=true}); } /// ///根据条件批量修改文档 /// ///修改条件-形如:Builders/ .Update.Set(filed,value) /// 查询条件Builders/ .Filter.Eq(filed,value) /// 修改影响文档数 publicvirtualvoidUpdateBatchAsync(UpdateDefinitionupdate,FilterDefinition filter) { _collection.UpdateManyAsync(filter,update,newUpdateOptions(){IsUpsert=true}); } #endregion #region查询 #regionGetCollection /// ///获取操作对象的IMongoCollection集合,强类型对象集合 /// ///publicvirtualIMongoCollection GetCollection() { return_database.GetCollection (typeof(T).Name); } #endregion #regionGetSingle /// ///查询数据库,检查是否存在指定ID的对象 /// ///对象的ID值 /// 存在则返回指定的对象,否则返回Null publicvirtualTGetById(stringid) { varfilterBuilder=Builders.Filter; varfilter=filterBuilder.Eq("Id",newObjectId(id)); vardata=_collection.Find(filter).FirstOrDefault(); returndata; } /// ///查询数据库,检查是否存在指定ID的对象 /// ///对象的ID值 /// 存在则返回指定的对象,否则返回Null publicvirtualasyncTaskGetAsyncById(stringid) { varfilterBuilder=Builders .Filter; varfilter=filterBuilder.Eq("Id",newObjectId(id)); vardata=await_collection.FindAsync(filter); returnawaitdata.SingleOrDefaultAsync(); } /// ///查询数据 /// ///过滤条件 /// publicvirtualTGet(FilterDefinition filter) { return_collection.Find(filter).FirstOrDefault(); } /// ///查询数据 /// ///条件表达式 /// publicvirtualTGet(Expression >filter) { return_collection.Find(filter).FirstOrDefault(); } /// ///查询数据 /// ///过滤条件 /// publicvirtualasyncTask GetAsync(FilterDefinition filter) { vardata=await_collection.FindAsync(filter); returnawaitdata.SingleOrDefaultAsync(); } /// ///查询数据 /// ///条件表达式 /// publicvirtualasyncTask GetAsync(Expression >filter) { vardata=await_collection.FindAsync(filter); returnawaitdata.SingleOrDefaultAsync(); } #endregion #regionGetMany /// ///查询部分数据 /// ///过滤条件 /// publicvirtualIEnumerable GetMany(FilterDefinition filter) { return_collection.Find(filter).ToEnumerable(); } /// ///查询部分数据 /// ///条件表达式 /// publicvirtualIEnumerable GetMany(Expression >filter) { //return_collection.AsQueryable().Where(filter).ToList(); //return_collection.AsQueryable().Where(filter); return_collection.Find(filter).ToEnumerable();//.ToEnumerable(); } /// ///查询部分数据 /// ///过滤条件 /// publicvirtualasyncTask >GetManyAsync(FilterDefinition filter) { vardata=await_collection.FindAsync(filter); returnawaitdata.ToListAsync(); } /// ///查询部分数据 /// ///过滤条件 /// publicvirtualasyncTask >GetManyAsync(Expression >filter) { vardata=await_collection.FindAsync(filter); returnawaitdata.ToListAsync(); } #endregion #regionGetAll /// ///查询所有记录,复杂查询直接用Linq处理(避免全表扫描) /// ///要查询的对象 publicvirtualIEnumerableGetAll() { vardata=_collection.AsQueryable(); returndata.ToEnumerable(); } /// ///查询所有记录,复杂查询直接用Linq处理(避免全表扫描) /// ///要查询的对象 publicvirtualasyncTask>GetAllAsync() { vardata=_collection.AsQueryable(); returnawaitdata.ToListAsync(); } /// ///查询所有记录,复杂查询直接用Linq处理(避免全表扫描) /// ///要查询的对象 publicvirtualIQueryableGetAllQueryable() { return_collection.AsQueryable(); } #endregion #regionMapReduce /// ///MapReduce /// ///返回一个List列表数据 publicIEnumerableGetMap(BsonJavaScriptmap,BsonJavaScriptreduce) { return_collection.MapReduce (map,reduce).ToList(); } #endregion #endregion } }
好了,就介绍到这里。