惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Privacy International News Feed
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
G
GRAHAM CLULEY
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
S
Schneier on Security
T
Troy Hunt's Blog
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
S
Security Affairs
WordPress大学
WordPress大学
T
Tailwind CSS Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
S
Securelist
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
爱范儿
爱范儿
Help Net Security
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
C
CERT Recently Published Vulnerability Notes
C
Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Spread Privacy
Spread Privacy
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
博客园 - 司徒正美
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
罗磊的独立博客
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
J
Java Code Geeks
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位

博客园 - 魏琼东

基于自然语言处理技术的智能电子病历系统 重写AgileEAS.NET SOA 中间件平台账号密码的加密算法 基于AgileEAS.NET SOA 中间件领域模型数据器快速打造自己的代码生成器 AgileEAS.NET SOA 中间件Web运行容器管理功能已全部开源,欢迎大家下载、使用、反馈 centos+scala2.11.4+hadoop2.3+spark1.3.1环境搭建 AgileEAS.NET SOA中间件平台更新日志 2015-04-28 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载 3小时搞定一个简单的MIS系统案例Northwind,有视频、有源代码下载、有真相 WinForm/MIS项目开发之中按钮级权限实践 MIS系统开发利器,实施、维护人员自定义报表的福音,AgileEAS.NET SOA平台动态报表指南 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍 高并发应用场景下的负载均衡与故障转移实践,AgileEAS.NET SOA 负载均衡介绍与实践 MIS系统开发利器,快速的字典录入解决方案,另类的、可管理的.NET DataWindow 犀利的报表系统,发票据与报表开发的快速利器,AgileEAS.NET SOA中间件GReport使用指南 拉风的服务器监控工具,随时掌握服务器动态,AgileEAS.NET SOA 平台服务器监控工具集介绍 使用DotNetBar制作漂亮的WinFrom界面,自定义AgileEAS.NET SOA平台WinClient主界面 基于AgileEAS.NET SOA 平台SAAS架构技术的开源分销ERP系统-SmartERP.NET下载配置说明 AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(四):开源的Silverlight运行容器的编译、配置
本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github
魏琼东 · 2015-07-17 · via 博客园 - 魏琼东

一、关于NoSQL的项目需求

     这些年在做AgileEAS.NET SOA 中间件平台的推广、技术咨询服务过程之中,特别是针对我们最熟悉的医疗行业应用之中,针对大数据分析,大并发性能的需求,我们也在慢慢的引用NoSQL技术来满足数据分析与性能等多方面的需要,也进一步完善我们的SOA基石架构风格:

image_thumb[11]

     在早些年,对NoSQL不是很了解这前,后端数据存储都是存储的单一的关系数据库之上,但是在很多时间,这并不是最优的,比如在医疗用户之中针对一个病人的相关数据展示,及相关性分析,关于数据库就不是最优的,另外一个,电子病历系统的之中的结构化/半结构化病历文档的存储、检索,以及更高级的应用,结构化病历数据挖掘,之前使用关系数据库存储或者使用文件存储,很难发挥病历数据的科研和统计、分析需求。

    在目前我们的医疗信息化应用之中,我们针对这两部分数据都引入了NoSQL存储,针对住院患者的领域相关性数据==》即病人聚合根对象相关数据,我们即在关系数据库以多表存储病人数据以及病人相关的医嘱、费用、检验、检查、护理等相关信息,同时我们也在NoSQL数据库存储患者的聚合根对象:

0NO5MFOQW74SFJC`@6R(@_3

    在NoSQL数据库之中的存储:

~NHW)0EH_0OC$KA7~8LYITU

    另外在电子病历应用之中,病历文档也是直接存入NoSQL之中。

    在接触巨杉数据库之前,我们一直使用MongoDB这款NoSQL产品,这是一款广为人知的NoSQL产品,使用者众多,C#的驱动也非常完善,案例也比比皆时。

三、关于巨杉(sequoiadb)数据库

     巨杉数据库是国人开发的一款企业级NoSQL数据库,目前已开源,官网http://www.sequoiadb.com/
初次了解到巨杉(sequoiadb)数据还是源于一个客户,因为我们项目一直使用MongoDB,客户就向我们提到巨杉(sequoiadb)数据库,说国内有人开发了这么一个NoSQL数据库,并且在平安银行有过成功应用,并且因为是国人开发,所以应该相比较MongoDB,应该能得到官方的支持,客户也和巨杉(sequoiadb)官方的人有过接触,官方也答应可以做一些支持。

     根据网上所公开的一些信息,巨杉(sequoiadb)数据库和MongoDB非常的接近,都是文档型数据库,同样的设计思路,集合和文档,同样的文档格式,Json/Bson。
根据最近一段时间的了解和完善C#驱动的过程来说,相对MongoDB,巨杉(sequoiadb)提供了更加方便的图形化部署和简单的Web管理界面:

image

     以下是SequoiaDB与MongoDB及其他NoSQL数据的功能对比:

     比较特别是的SequoiaDB支持事务和SQL语法,当然了,这两点在目前情况下我们都使用使用过。

四、关于SequoiaDB的C#驱动

     SequoiaDB官方提供C、C++、JAVA、C#、php、Python驱动以及REST架构风格的接口,据官方的说法是Java的驱动很成熟,但是C#的驱动很简单,只能支持最基本的Bson格式的接口,如下代码:

// Insert
            BsonDocument insertor = new BsonDocument();
            insertor.Add("Last Name", "Lin");
            insertor.Add("First Name", "Hetiu");
            insertor.Add("Address", "SYSU");
            BsonDocument sInsertor = new BsonDocument();
            sInsertor.Add("Phone", "10086");
            sInsertor.Add("EMail", "hetiu@yahoo.com.cn");
            insertor.Add("Contact", sInsertor);
            ObjectId insertID = (ObjectId)coll.Insert(insertor);
            Assert.IsNotNull(insertID);

            // Update
            DBQuery query = new DBQuery();
            BsonDocument updater = new BsonDocument();
            BsonDocument matcher = new BsonDocument();
            BsonDocument modifier = new BsonDocument();
            updater.Add("Age", 25);
            modifier.Add("$set", updater);
            matcher.Add("First Name", "Hetiu");
            query.Matcher = matcher;
            query.Modifier = modifier;
            coll.Update(query);

            // Query
            DBCursor cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            BsonDocument bson = cursor.Next();
            Assert.IsNotNull(bson);
            Assert.IsTrue(bson["First Name"].AsString.Equals("Hetiu"));
            Assert.IsTrue(bson["Age"].AsInt32.Equals(25));

            // Delete
            BsonDocument drop = new BsonDocument();
            drop.Add("Last Name", "Lin");
            coll.Delete(drop);
            query.Matcher = drop;
            cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            bson = cursor.Next();
            Assert.IsNull(bson);

     集合查询:

for (int i = 0; i < 10; ++i)
            {
                string date = DateTime.Now.ToString();
                BsonDocument insertor = new BsonDocument();
                insertor.Add("operation", "Query");
                insertor.Add("date", date);
                coll.Insert(insertor);
            }
            BsonDocument matcher = new BsonDocument();
            DBQuery query = new DBQuery();
            matcher.Add("operation", "Query");
            query.Matcher = matcher;
            query.ReturnRowsCount = 5;
            query.SkipRowsCount = 5;
            DBCursor cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            int count = 0;
            while (cursor.Next() != null)
            {
                ++count;
                BsonDocument bson = cursor.Current();
                Assert.IsNotNull(bson);
            }
            Assert.IsTrue(count == 5);

     官方的代码有点简单,这不符合我们写代码的风格,目前业务系统大量的使用对象操作和Linq处理,原始的Bson接口,这个不科学。

五、完善改造SequoiaDB的C#驱动

     即然官方的驱动太简单,不支持对象处理,也不支持Linq,很不科学,那么应该怎么办呢,其实第一个观点当然是放弃,我们原本使用MongoDB跑的好好的,为什么要给自己找事呢,但是出于项目运维的观点,以及支持国人产品的想法,最终决定自己完善和写一个。

     那么如何来写呢,当然是他山之石,可以攻玉,因为之前做MongoDB开发,原始的驱动配置我们的ORM跑起来也有一些问题,最早我们使用的非MongoDB的官方驱动,而是第三方驱动samus,不支持Decimal类型,但是我们项目之中有大量的Decimal类型,那么办呢,修改驱动,后来我们又换成了MongoDB的官方驱动,因为XmlIgnore标签和Id映射的问题也认真的读过MongoDB的官方驱动,对MongoDB的C#驱动比较熟悉。

     所以完善SequoiaDB的C#的思路就变成了结合SequoiaDB的原始驱动和MongoDB的官方驱动,提供一个类似于MongoDB驱动的操作风格的驱动,在SequoiaDB驱动的基础上提供了,直接操作C#对象的方案和支持Linq进行查询、修改、删除的功能。

     经本人完善修改之后的驱动的操作风格如下:

Sequoiadb sdb = new Sequoiadb("192.168.23.57:50000");
            sdb.Connect("", "");

            //求集合空间。
            var cs = sdb.GetCollecitonSpace("dbo");

            //求集合。
            var coll = cs.GetCollection<HFareDetail>();

            //执行数据插入。
            List<HFareDetail> vList =null;
            using (AgileHIS.Entities.DbEntities db = new AgileHIS.Entities.DbEntities())
            {
                vList = db.HFareDetails.ToList();
                //插入。
                foreach (var item in vList)
                {
                    coll.Insert(item);
                }
                System.Console.WriteLine(string.Format("insert {0} records", vList.Count));
                System.Console.ReadLine();
            }

            //按条件修改某一条数据的几个属性值。
            var v1 = vList.FirstOrDefault();
            v1.Name = string.Empty;
            v1.Cash = decimal.Zero;
            coll.Update(v1, p => p.ID == v1.ID);
            //按条件指量修改,指定某几个必,其他属性全部置空。
            coll.Update(p => new HFareDetail { Cash = decimal.Zero, Name = string.Empty, Price = decimal.Zero }, p => p.ChargeTime >DateTime.Now.AddDays(-1));
            //依据条件删除
            coll.Delete(p => p.ChargeTime > DateTime.Now.AddDays(-1));

            //求Count
            int count = coll.AsQueryable<HFareDetail>()
                .Where(p => p.SourceID==0)
                .Count();

            //Linq查询Take\Skip。
            var vList2 = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .Skip(10).Take(1000)
                .ToList();
            System.Console.WriteLine(string.Format("query {0} records", vList.Count));

            //Linq查询过。
            var vFare = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .FirstOrDefault();
            System.Console.WriteLine(vFare);

            //Linq\聚合运算,目前因为测试驱动报错,暂未实现
            var sum = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .Sum(p => p.Cash);

            System.Console.ReadLine();

     看看,代码是不是很清爽,很方便了呢,没有了bson,只有对象,Linq。

六、SequoiaDB、MongoDB与AgileEAS.NET SOA整合

     AgileEAS.NET SOA之前只支持MongoDB,最近要支持SequoiaDB,我们就得考虑对原有代码的兼容,或者说,更希望自己的医疗系统能够在业务上同时支持MongoDB和SequoiaDB,达到使用环境之中不管是选择MongoDB还是选择SequoiaDB都是同样的代码,为此,我们在AgileEAS.NET SOA中间件之中定义了一个IStructDbProvider接口:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace EAS.Data
{
    /// <summary>
    /// 结构化数据库提供者接口定义。
    /// </summary>
    /// <remarks>
    /// 为AgileEAS.NET SOA 中间件NoSQL数据访问提供标准接口定义。
    /// </remarks>
    public interface IStructDbProvider
    {
        /// <summary>
        /// 打开连接。
        /// </summary>
        void Connect();

        /// <summary>
        /// 关闭连接。
        /// </summary>
        void Close();

        /// <summary>
        /// 连接是否打开。
        /// </summary>
        bool IsOpen { get; }

        /// <summary>
        /// 对象插入。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="item">对象实例。</param>
        void Insert<T>(T item) where T : class;

        /// <summary>
        /// 对象批量插入。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="items">对象实例。</param>
        void InsertBatch<T>(System.Collections.Generic.IEnumerable<T> items) where T : class;

        /// <summary>
        /// 根据条件执行更新操作。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="updater">更新表达式。</param>
        /// <param name="func">查询条件。</param>
        void Update<T>(Expression<Func<T, T>> updater, Expression<Func<T, bool>> func) where T : class;

        /// <summary>
        /// 根据条件执行更新操作。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="item">更新对象。</param>
        /// <param name="func">查询条件。</param>
        void Update<T>(T item, System.Linq.Expressions.Expression<Func<T, bool>> func) where T : class;

        /// <summary>
        /// 根据条件删除对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="func">条件表达式。</param>
        void Delete<T>(Expression<Func<T, bool>> func) where T : class;
        
        /// <summary>
        /// 求出Linq查询表达式。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <returns>对象表达式包装。</returns>
        IQueryableWarp<T> Linq<T>() where T : class;

        /// <summary>
        /// 根据条件查询数制。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="where">条件。</param>
        /// <param name="skip">跳过记录数。</param>
        /// <param name="take">取记录数。</param>
        /// <returns>查询结构。</returns>
        List<T> List<T>(Expression<Func<T, bool>> where, int skip, int take) where T : class;

        /// <summary>
        /// 根据条件求单条记录。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="where">条件。</param>
        /// <returns>对象实例。</returns>
        T Single<T>(Expression<Func<T, bool>> where) where T : class;
    }
}

     IStructDbProvider字面意思即为结构化数据访问提供者接口,本接口定义在EAS.MicroKernel.dll程序集之中,AgileEAS.NET SOA中间件同时提供了针对SequoiaDB和MongoDB数据库的IStructDbProvider实现,EAS.Data.MongoDbProvider和EAS.Data.SequoiaDbProvider,这两个实现类定义在EAS.Data.NoSQL.dll程序集之中。

     因为统计使用了IStructDbProvider接口,我们针对SequoiaDB和MongoDB的操作处理就统计成了如下代码:

var vContainer = EAS.Context.ContextHelper.GetContext().Container;
            var dbProvider = vContainer.GetComponentInstance("StructDbProvider") as IStructDbProvider;

            //执行数据插入。
            List<HFareDetail> vList = null;
            using (AgileHIS.Entities.DbEntities db = new AgileHIS.Entities.DbEntities())
            {
                vList = db.HFareDetails.ToList();
                //插入。
                foreach (var item in vList)
                {
                    dbProvider.Insert<HFareDetail>(item);
                }
                System.Console.WriteLine(string.Format("insert {0} records", vList.Count));
                System.Console.ReadLine();
            }

            //按条件修改某一条数据的几个属性值。
            var v1 = vList.FirstOrDefault();
            v1.Name = string.Empty;
            v1.Cash = decimal.Zero;
            dbProvider.Update<HFareDetail>(v1, p => p.ID == v1.ID);
            //按条件指量修改,指定某几个必,其他属性全部置空。
            dbProvider.Update<HFareDetail>(p => new HFareDetail { Cash = decimal.Zero, Name = string.Empty, Price = decimal.Zero }, p => p.ChargeTime > DateTime.Now.AddDays(-1));
            //依据条件删除
            dbProvider.Delete<HFareDetail>(p => p.ChargeTime > DateTime.Now.AddDays(-1));

            //求Count
            using (var queryWarp = dbProvider.Linq<HFareDetail>())
            {
                int count = queryWarp.Queryable
                .Where(p => p.SourceID == 0)
                .Count();

                //Linq查询Take\Skip。
                var vList2 = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .Skip(10).Take(1000)
                    .ToList();
                System.Console.WriteLine(string.Format("query {0} records", vList.Count));

                //Linq查询过。
                var vFare = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .FirstOrDefault();
                System.Console.WriteLine(vFare);

                //Linq\聚合运算,目前因为测试驱动报错,暂未实现
                var sum = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .Sum(p => p.Cash);
            }

            System.Console.ReadLine();

     具体是使用SequoiaDB还是使用MongoDB由系统配置文件来决定,使用SequoiaDB:

<!--StructDb/SequoiaDb-->
      <object name="StructDbProvider" assembly="EAS.Data.NoSQL" type="EAS.Data.SequoiaDbProvider" LifestyleType="Thread">
        <property name="ConnectionString" type="string" value="192.168.23.57:50000"/>
        <property name="UserName" type="string" value=""/>
        <property name="Password" type="string" value=""/>
        <property name="CollectionSpace" type="string" value="his"/>
      </object>

     使用MongoDB。

<!--StructDb/MongoDb-->
      <object name="StructDbProvider" assembly="EAS.Data.NoSQL" type="EAS.Data.MongoDbProvider" LifestyleType="Thread">
        <property name="ConnectionString" type="string" value="mongodb://sa:sa@127.0.0.1:2222/his"/>
        <property name="DbName" type="string" value="his"/>
      </object>

七、SequoiaDB的C#驱动源代码托管、下载

     本人为SequoiaDB所写的C#驱动,已提交托管到github,项目地址https://github.com/agilelab/SequoiaDB.Charp,欢迎大家下载,也欢迎大家和本人一道完善本驱动。

八、联系我们

     敏捷软件工程实验室,是一家研究、推广和发展新技术,并致力于提供具有自主知识产权的业务基础平台软件,以及基于业务基础平台开发的管理软件的专业软件提供商。主要业务是为客户提供软件企业研发管理解决方案、企业管理软件开发,以及相关的技术支持,管理及技术咨询与培训业务。

     AgileEAS.NET SOA中间件平台自2004年秋呱呱落地一来,我就一直在逐步完善和改进,也被应用于保险、医疗、电子商务、房地产、铁路、教育等多个应用,但一直都是以我个人在推广,2010年因为我辞职休息,我就想到把AgileEAS.NET推向市场,让更多的人使用。

     我的技术团队成员都是合作多年的老朋友,因为这个平台是免费的,所以也没有什么收入,都是由程序员的那种理想与信念坚持,在此我感谢一起奋斗的朋友。

团队网站:http://www.agilelab.cn

AgileEAS.NET网站:http://www.agileeas.net

官方博客:http://eastjade.cnblogs.com

github:https://github.com/agilelab/eas

QQ:47920381,AgileEAS.NET

QQ群:113723486(AgileEAS SOA 平台)/上限1000人

199463175(AgileEAS SOA 交流)/上限1000人

212867943(AgileEAS.NET研究)/上限500人

147168308(AgileEAS.NET应用)/上限500人

172060626(深度AgileEAS.NET平台)/上限500人

116773358(AgileEAS.NET 平台)/上限500人

125643764(AgileEAS.NET探讨)/上限500人

193486983(AgileEAS.NET 平台)/上限500人

邮件:james@agilelab.cn,mail.james@qq.com,

电话:18629261335。