使用MongoDB和 ASP.NET MVC实现高性能搜索

分享于 

7分钟阅读

数据库

  繁體

在本文中,我们将讨论一种解决方案,该解决方案将基于SQL Server的搜索替换为基于MongoDB的搜索。

MongoDB是一种面向对象的文档数据库实现,它是NoSQL数据库的一种,NoSQL是传统关系型DMBS的替代方法,它解决了关系数据库的一些限制,尽管通常在DBMS级别上以标准化或引用完整性为代价,文档数据库是一种NoSQL数据库,它将一个键与一个复杂的数据结构(称为文档,文档可以包含一个或多个key-value对,NoSQL数据库有更简单的结构,没有强制引用完整性的开销,它们比关系数据库更具可伸缩性,并提供更好的搜索性能。

MongoDB安装和服务器架构

我将MongoDB安装在ubuntu14.0.4LTS64位 VMWarePlayer虚拟机中,该虚拟机与Windows域控制器和IIS服务器位于同一虚拟网络中。

#bind_ip = 127.0.0.1#port = 27017

现在,通过注释掉bind_ip值,允许所有到MongoDB服务器的远程连接。

数据体系结构

在Visual Studio项目中,在客户端搜索页面上将后端数据源从SQL-Server更改为MongoDB,然而,第一步是在MongoDB数据库中决定文档的模式,我们希望显着提高搜索性能,以便即使是具有较大结果集的复杂搜索也可以从服务器中以亚秒级的响应时间返回数据。对于个人搜索,我们只关心客户的主电话号码,地址和帐号,因此,为了利用MongoDB (在平面文档中搜索属性)的强大功能,压缩每个人的分层数据到MongoDB文档中的单个记录中,代替关系数据库的分层模式,有一个平面文档,如下所示。

MongoDB数据库中的这种扁平文档将为客户端搜索页面提供更好的搜索性能。

MongoDB C#驱动程序和服务层

MongoDB c#驱动程序可以使用NuGet从Visual Studio中下载。使用C#驱动程序,可以使用C#和LINQ连接到MongoDb实例,并操作文档存储区中的数据。

决定模式之后的下一步是根据文档的模式创建一个物理模型,在例子中,我在PersonDocument中创建了一个PersonDocument.cs,我在服务层代码和MongoDB驱动程序(数据传输对象)之间用作DTO,驱动程序将此对象序列化为MongoDB文档存储的BSON格式。

publicclass PersonDocument
 {
 publicint PersonID { get; set; }
 publicstring FirstName { get; set; }
 publicstring LastName { get; set; }
 publicstring EmailAddress { get; set; }
 publicstring PhoneNumber { get; set; }
 publicstring StreetAddress { get; set; }
 publicstring City { get; set; }
 publicstring County { get; set; }
 publicstring State { get; set; }
 publicstring Zip { get; set; }
 }

Search service方法使用IQueryable接口在的Person方法中搜索文档。

IQueryable<PersonDocument> personsQueryable = unitOfWork.Persons.GetQueryable();

ETL过程使用AddBatch方法DocumentRepository将记录添加到Person文档存储。

var docUnitOfWork = new FootlooseFSDocUnitOfWork();
 docUnitOfWork.Persons.AddBatch(personDocuments);

回到MongoDB数据库的工作单元类,对于使用MongoDB工作单元和DocumentRepository的任何客户端(ASP.NET Web和ETL流程),都有一些应用程序配置键是必需的。对于ASP.NET web应用程序,它们将在web.config和ETL独立程序中,在App.config中,MongoDBConnectionString键包含MongoDB连接字符串,它实际上是网络上MongoDB主机的IP地址或DNS,MongoDBDatabaseName是包含一个或多个文档存储的MongoDB数据库的名称。

<add key="MongoDBConectionString"value="mongodb://192.168.1.6"/>
<add key="MongoDBDatabaseName"value="footloosefs"/>

MongoDB的工作单元类有一个private MongoDatabase变量,该变量包含到数据库的连接和连接初始化代码,在这里使用配置值 DocRepository<PersonDocument> 对象有对person文档存储执行CRUD操作的代码,默认情况下,MongoDB将在每个文档中创建一个object ID字段作为主键。

publicclass FootlooseFSDocUnitOfWork
{
 private MongoDatabase _database;
 protected DocRepository<PersonDocument> _persons;
 public FootlooseFSDocUnitOfWork()
 {
 var connectionString = ConfigurationManager.AppSettings["MongoDBConectionString"];
 var client = new MongoClient(connectionString);
 var server = client.GetServer();
 var databaseName = ConfigurationManager.AppSettings["MongoDBDatabaseName"];
 _database = server.GetDatabase(databaseName); 
 }
 public IRepository<PersonDocument> Persons
 {
 get {
 if (_persons == null)
 _persons = new DocRepository<PersonDocument>(_database, "persons");
 return _persons;
 }
 } 
 publicstaticvoid Init()
 {
 BsonClassMap.RegisterClassMap<PersonDocument>(cm => {
 cm.MapIdProperty(p => p.PersonID);
 cm.MapProperty(p => p.FirstName);
 cm.MapProperty(p => p.LastName);
 cm.MapProperty(p => p.EmailAddress);
 cm.MapProperty(p => p.PhoneNumber);
 cm.MapProperty(p => p.StreetAddress);
 cm.MapProperty(p => p.City);
 cm.MapProperty(p => p.County);
 cm.MapProperty(p => p.State);
 cm.MapProperty(p => p.Zip);
 });
 }
}

asp  asp-net  HIG  PERF  搜索  性能