MongoDB在windows下
1.安装 官网下载直接下一步 略过
>会默认安装为windows服务,但是也可以通过命令行启动mongodb服务:mongod -dbpath "C:\Program Files\MongoDB\Server\4.2\data\db" --auth
参数根据需要增减, --auth表示开启权限检验
2.用户权限模块
1)MongoDB默认情况下没有认证,即便是游客也拥有管理员权限,我们可以在没有认证的情况下新建用户,然后再重新启动服务,开启权限校验;
开启权限校验有两种办法:
a)命令行参数;
b)配置文件 #security:
authorization: enabled
2)内置角色
所有数据库都有:
数据库用户角色:read、readWrite 非系统集合读写
数据库用户管理角色:dbAdmin 提供执行管理任务的功能,此角色不授予用户和角色管理权限
dbOwner = readWrite + dbAdmin + userAdmin
userAdmin:创建修改角色、用户
仅admin数据库具有:
集群管理角色:clusterAdmin = clusterManager+clusterMonitor+hostManger
clusterManager、clusterMonitor、hostManager
备份和回复角色:backup、restore
仅在admin数据库中存在,并提供适用于所有数据库,除了local、config:
readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超级用户角色:
root = readWriteAnyDatabase+DBAdminAnyDatabase+UserAdminAnyDatabase+ClusterAdmin+Restore+Backup
内部角色:
_system:提供对数据库中的任何对象执行任何操作的权限。
3)相关命令
创建用户:
db.createUser({ user:<name_string>, #字符串 pwd:<password_string>, #字符串 roles:[{role:<role_name>,db:<db_name>}] #数组+对象 })
删除用户:db.dropUser("userName") 、db.dropAllUser()
更新用户: db.updateUser("usertest",{pwd:"changepass1"});
当前数据库所有用户:show users
查看系统所有用户:admin 数据库下 db.system.users.find()
3.c# 操作MongoDB
>nuget MongoDB.Driver
>连接字符串:
>两个帮助类:
public class MongoDBManager { private static MongoClient _mongoClient; //初始化MongoDB数据库链接 static MongoDBManager() { _mongoClient = new MongoClient(ConfigurationManager.ConnectionStrings["Mongodb"].ToString()); } public static IMongoDatabase GetDataBase() { string dbName = ConfigurationManager.AppSettings.Get("dbName"); if (string.IsNullOrEmpty(dbName)) { dbName = "admin"; } return _mongoClient.GetDatabase(dbName); } }
public class MongoDBHelper<T> where T : BaseEntity { private IMongoDatabase _db = null; private IMongoCollection<T> _collection = null; public MongoDBHelper() { this._db = MongoDBManager.GetDataBase(); this._collection = _db.GetCollection<T>(typeof(T).Name); } #region Insert public T InsertOne(T entity, InsertOneOptions options = null, CancellationToken cancellationToken = default) { entity.GetType().GetProperty("Id").SetValue(entity, ObjectId.GenerateNewId()); _collection.InsertOne(entity, options, cancellationToken); return entity; } public IEnumerable<T> InsertMany(IEnumerable<T> TList, InsertManyOptions options = null, CancellationToken cancellationToken = default) { TList.ToList().ForEach(l => l.GetType().GetProperty("Id").SetValue(l, ObjectId.GenerateNewId())); _collection.InsertMany(TList, options, cancellationToken); return TList; } public async Task<T> InsertOneAsync(T entity, InsertOneOptions options = null, CancellationToken cancellationToken = default) { entity.GetType().GetProperty("Id").SetValue(entity, ObjectId.GenerateNewId()); await _collection.InsertOneAsync(entity, options, cancellationToken); return entity; } public async Task<IEnumerable<T>> InsertManyAsync(IEnumerable<T> TList, InsertManyOptions options = null, CancellationToken cancellationToken = default) { TList.ToList().ForEach(l => l.GetType().GetProperty("Id").SetValue(l, ObjectId.GenerateNewId())); await _collection.InsertManyAsync(TList, options, cancellationToken); return TList; } #endregion #region Delete public DeleteResult DeleteOne(string id, DeleteOptions options = null, CancellationToken cancellationToken = default) { return DeleteOne(ObjectId.Parse(id), options, cancellationToken); } public DeleteResult DeleteOne(ObjectId id, DeleteOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", id); return _collection.DeleteOne(filter, options, cancellationToken); } public async Task<DeleteResult> DeleteOneAsync(string id, DeleteOptions options = null, CancellationToken cancellationToken = default) { return await DeleteOneAsync(ObjectId.Parse(id), options, cancellationToken); } public async Task<DeleteResult> DeleteOneAsync(ObjectId id, DeleteOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", id); return await _collection.DeleteOneAsync(filter, options, cancellationToken); } public DeleteResult DeleteMany(Expression<Func<T, bool>> func, DeleteOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); return _collection.DeleteMany(filter, options, cancellationToken); } public async Task<DeleteResult> DeleteManyAsync(Expression<Func<T, bool>> func, DeleteOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); return await _collection.DeleteManyAsync(filter, options, cancellationToken); } #endregion #region replace public ReplaceOneResult ReplaceOne(T entity, ReplaceOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", entity.Id); return _collection.ReplaceOne(filter, entity, options, cancellationToken); } public async Task<ReplaceOneResult> ReplaceOneAsync(T entity, ReplaceOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", entity.Id); return await _collection.ReplaceOneAsync(filter, entity, options, cancellationToken); } #endregion #region Update public UpdateResult UpdateOne(string id, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { return UpdateOne(ObjectId.Parse(id), updateFields, options, cancellationToken); } public UpdateResult UpdateOne(ObjectId id, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", id); BsonDocument bsonDocument = new BsonDocument(updateFields); bsonDocument = new BsonDocument { { "$set", bsonDocument } }; return _collection.UpdateOne(filter, bsonDocument, options, cancellationToken); } public async Task<UpdateResult> UpdateOneAsync(string id, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { return await UpdateOneAsync(ObjectId.Parse(id), updateFields, options, cancellationToken); } public async Task<UpdateResult> UpdateOneAsync(ObjectId id, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", id); BsonDocument bsonDocument = new BsonDocument(updateFields); bsonDocument = new BsonDocument { { "$set", bsonDocument } }; return await _collection.UpdateOneAsync(filter, bsonDocument, options, cancellationToken); } public UpdateResult UpdateMany(Expression<Func<T, bool>> func, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); BsonDocument bsonDocument = new BsonDocument(updateFields); bsonDocument = new BsonDocument { { "$set", bsonDocument } }; return _collection.UpdateMany(filter, bsonDocument, options, cancellationToken); } public async Task<UpdateResult> UpdateManyAsync(Expression<Func<T, bool>> func, Dictionary<string, object> updateFields, UpdateOptions options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); BsonDocument bsonDocument = new BsonDocument(updateFields); bsonDocument = new BsonDocument { { "$set", bsonDocument } }; return await _collection.UpdateManyAsync(filter, bsonDocument, options, cancellationToken); } #endregion #region query public T Find(Expression<Func<T, bool>> func, FindOptions options = null) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); return _collection.Find(filter, options).ToList().FirstOrDefault(); } public T Find(string id, FindOptions options = null) { return Find(ObjectId.Parse(id), options); } public T Find(ObjectId id, FindOptions options = null) { FilterDefinition<T> filter = Builders<T>.Filter.Eq("Id", id); return _collection.Find(filter, options).ToList().FirstOrDefault(); } public List<T> FindMany(Expression<Func<T, bool>> func, FindOptions options = null) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); return _collection.Find(filter, options).ToList(); } public async Task<List<T>> FindAsync(Expression<Func<T, bool>> func, FindOptions<T, T> options = null, CancellationToken cancellationToken = default) { FilterDefinition<T> filter = Builders<T>.Filter.Where(func); IAsyncCursor<T> result = await _collection.FindAsync(filter, options, cancellationToken); return result.ToList(); } #endregion #region page /// <summary> /// 延迟查询的分页 /// </summary> /// <param name="where">分页查询条件</param> /// <param name="currentPageNum">当前页数</param> /// <param name="MaxNum">每页记录数</param> /// <param name="totalNum">总记录数</param> /// <returns></returns> public IEnumerable<T> GetPageList(Func<T, bool> where, int currentPageNum, int MaxNum, out int totalNum) { var queryable = _collection.AsQueryable(); totalNum = queryable.Count(); return queryable.Where(where).Skip((currentPageNum - 1) * MaxNum).Take(totalNum); } #endregion }
遇到的问题:
1.将对象序列化成Bson会有“标记”,
User user = new User() {Id=ObjectId.GenerateNewId(),Name="序列化测试",Hobby = new List<string>() { "阅读","电影"} }; BsonDocument bd = new BsonDocument(); BsonSerializer.Serialize(new BsonDocumentWriter(bd), user);
序列化结果: 其中“_t”是不需要的,解决办法重新继承IDiscriminatorConvention接口,自定义discriminator:
如下:
public class NoDiscriminatorConvention: IDiscriminatorConvention { public string ElementName => null; public Type GetActualType(IBsonReader bsonReader, Type nominalType) => nominalType; public BsonValue GetDiscriminator(Type nominalType, Type actualType) => null; }
将自定义的discriminator注册:BsonSerializer.RegisterDiscriminatorConvention(typeof(BaseEntity), new NoDiscriminatorConvention());
2.MongoDB中存储的时间不是本地时间,是UTC时间,解决办法:
>在对象的时间属性上,加上 [BsonDateTimeOptions(Kind = DateTimeKind.Local)] 属性
>或者继承DateTimeSerializer,自定义时间序列化器