About neohope

一直在努力,还没想过要放弃...

远程预诊存在的问题

现在不少公司在推远程预诊,或者视频问诊,但没有一家真正解决了下面的问题:
1、没有足够的专业医疗队伍资源,在我的另一篇博文中已经说明原因,并指出医学院学生及退休医生是可以考虑的资源
2、没有专业设备,可以获取患者的第一手资料。必须有设备的技术变革,例如大白去掉AI功能。(高清视频音频、心率、血压、脉搏、血糖、呼吸等等等等)
3、没有好的盈利模式,单纯靠吸引患者就诊不太可取,单纯靠卖保健品。。。
4、没有解决患者实际问题,预诊后要做什么呢(请到XX医院做进一步治疗?),患者仅仅多排了一次队浪费时间而已
5、患者不信任,不愿意承担风险,需要一个漫长的过程

那现在能做的是什么呢?
1、慢性病的跟踪治疗,比如高血压、糖尿病等
2、私人诊所的个人咨询
3、私人护理的定期巡诊

与上面最大的区别是什么呢?
1、医患之间有过接触,有了信任
2、医生了解患者的病情
3、患者病情不是很紧急
4、医院可以持续盈利

要预防什么呢?
1、高大上的产品变成了产品推销平台
2、打擦边球,因此医疗事故,触犯法律
3、乱烧钱,最后不了了之

MongoDB的ObjectId(Shell)

MongoDB中存储的文档必须有一个”_id”键。这个键的值可以是任何类型的,默认是个ObjectId对象。该_id用来确保集合里面每个文档都能被唯一标识,并用来在多个服务器上同步数据。

ObjectId是一个12字节BSON类型数据,格式如下:
前4个字节表示时间戳
接下来的3个字节是机器标识码
接的两个字节由进程id组成(PID)
最后三个字节是随机数

myObjectId = ObjectId()
myObjectId.getTimestamp()

ACID、BASE与CAP

一、关系型数据库遵循的ACID原则

1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。

比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。

2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。

3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。

4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

二、非关系型数据库遵循的BASE原则
BASE:Basically Available, Soft-state, Eventually Consistent。 由 Eric Brewer 定义。
1、Basically Availble –基本可用
2、Soft-state –软状态/柔性事务。 “Soft state” 可以理解为”无连接”的, 而 “Hard state” 是”面向连接”的
3、Eventual Consistency –最终一致性 最终一致性, 也是是 ACID 的最终目的。

三、CAP定理(CAP theorem)

在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
1、一致性(Consistency) (所有节点在同一时间具有相同的数据)
2、可用性(Availability) (保证每个请求不管成功或者失败都有响应)
3、分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA – 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP – 满足一致性,分区容忍必的系统,通常性能不是特别高。
AP – 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

CAP理论

举个例子来说,HBase与Cassandra,HBase在CAP中,更偏重于CP,客户端读到的数据是一致的,但性能会差;而Cassandra更偏重于AP,性能好一些,但有时客户端会读到不同的数据。

MongoDB聚合操作(Shell)

0、数据准备

for(var i=0;i<10000;i++){
var patid="pat"+i;
var patname="name"+i;
var sex="M";
var age=parseInt(100*Math.random(i));
db.patient.insert({"patid":patid,"patname":patname,"sex":sex,"age":age,address:{"city":"shanghai","street":"huaihai road"}});
}

1、count

db.patient.count({"age":12})

2、distinct

db.patient.distinct("age")

3、min, max, sum,avg

db.patient.aggregate([{$group:{_id:"$item",maxAge:{$max:"$age"}}}])
db.patient.aggregate([{$group:{_id:"$item",minAge:{$min:"$age"}}}])
db.patient.aggregate([{$group:{_id:"$item",sumAge:{$sum:"$age"}}}])
db.patient.aggregate([{$group:{_id:"$item",avgAge:{$avg:"$age"}}}])

4、group

db.patient.group({
"key":{"age":true},
"initial":{"patids":[]},
"reduce":function(item,out){out.patids.push(item.patid);},
"finalize":function(out){out.count=out.patids.length;},
"condition":{"age":{$lte:18}}
})

5、map reduce

map=function(){emit(this.age,1);}
reduce=function(key,values){return values.length;}
mropt={"out":"mrresult"}
db.patient.mapReduce(map,reduce,mropt).find()

MongoDB更新操作(Shell)

0、数据准备

for(var i=0;i<10000;i++){
var patid="pat"+i;
var patname="name"+i;
var sex="M";
var age=parseInt(100*Math.random(i));
db.patient.insert({"patid":patid,"patname":patname,"sex":sex,"age":age,address:{"city":"shanghai","street":"huaihai road"}});
}

1、默认为全局更新

db.patient.find({"patid":"pat100"})
db.patient.update({"patid":"pat100"},{"patid":"pat100","sex":"F"})
db.patient.find({"patid":"pat100"})

2、局部更新$set

db.patient.find({"patid":"pat101"})
db.patient.update({"patid":"pat101"},{$set:{"sex":"F"}})
db.patient.find({"patid":"pat101"})

3、局部更新$inc

db.patient.find({"patid":"pat102"})
db.patient.update({"patid":"pat102"},{$inc:{"age":-100}})
db.patient.find({"patid":"pat102"})

4、批量更新

db.patient.find({"age":10})
db.patient.update({"age":10},{$set:{"age":11}})
db.patient.find({"age":10})
db.patient.update({"age":10},{$set:{"age":11}},false,true)
db.patient.find({"age":10})

5、更新时,没有匹配则插入

db.patient.find({"patid":"pidx001"})
db.patient.update({"patid":"pidx001"},{"patid":"pidx001","sex":"F"},true)
db.patient.find({"patid":"pidx001"})

MongoDB实现条件查询(Shell)

0、数据准备

for(var i=0;i<10000;i++){
var patid="pat"+i;
var patname="name"+i;
var sex="M";
var age=parseInt(100*Math.random(i));
db.patient.insert({"patid":patid,"patname":patname,"sex":sex,"age":age,address:{"city":"shanghai","street":"huaihai road"}});
}

1、比较运算符

运算符 操作符
> $gt
>= $gte
< $lt
<= $lte
!= $ne
= $eq 或 空
db.patient.find({"age":20})
db.patient.find({"age":{$eq:20}})
db.patient.find({"age":{$ne:20}})
db.patient.find({"age":{$gt:20}})
db.patient.find({"age":{$gte:20}})
db.patient.find({"age":{$lt:20}})
db.patient.find({"age":{$lte:20}})

2、逻辑运算符

运算符 操作符
And $and
Or $or
db.patient.find({$and:[{"age":10},{"age":11}]})
db.patient.find({$or:[{"age":10},{"age":11}]})

3、IN 与 Not IN

运算符 操作符
In $in
not in nin
db.patient.find({"age":{$in:[10,11]}})
db.patient.find({"age":{$nin:[10,11]}})

4、where

db.patient.find({$where:function(){return this.patid=='pat1000'}})
db.patient.find({$where:function(){return this.patid=='pat1000' || this.age==1}})

5、正则表达式

#patid以0做结尾
db.patient.find({"patid":/0$/})
#patid以pat开头
db.patient.find({"patid":{$regex:"^pat"}})
#patid以pat开头,切不区分pat大小写
db.patient.find({"patid":{$regex:"^pat",$options:"$i"}})
#patid以pat1做开头,age为10
db.patient.find({"patid":/^pat1/,age:10})

6、分页与排序

db.patient.find({"patid":/0$/}).count()
db.patient.find({"patid":/0$/}).limit(10)
db.patient.find({"patid":/0$/}).skip(10).limit(10)
db.patient.find({"patid":/0$/}).sort({"age":1})
db.patient.find({"patid":/0$/}).sort({"age":-1})

7、between是由min max来实现的

#需要age字段的索引哦
db.patient.find({"patid":/0$/}).min({"age":10}).max({"age":20})

8、全文检索

#建立text索引后,mongo会帮你分词,一个collection只能建立一个text索引
#在patname字段建立全文索引
db.patient.ensureIndex({"address.street":"text"})
#在全部字段建立全文索引
db.patient.ensureIndex({"$**": "text"})
#进行简单查询
db.patient.find({$text:{$search:"huaihai"}})

MongoDB实现分片存储(Shell)

MongoDB分片存储结构如下图所示:
Mongo分片存储

#启动配置服务
mongod --dbpath=D:\Database\MongoDB3\slice\config --port 27018
#启动mongos
mongos --port 27017 --configdb=localhost:27018
#启动mongo分片服务
mongod --dbpath=D:\Database\MongoDB3\slice\slice1 --port 27019
mongod --dbpath=D:\Database\MongoDB3\slice\slice2 --port 27020
mongo localhost:27017
#增加节点
sh.addShard("localhost:27019")
sh.addShard("localhost:27020")
#开启分片
sh.enableSharding("test")
#配置collection
sh.shardCollection("test.patient",{"patid":1},true)
#查看状态
sh.status()
#批量插入数据
#单独连一个mongo查一下试试:)
for(var i=0;i<10000;i++){
var patid="pat"+i;
var patname="name"+i;
var sex="M";
var age=parseInt(100*Math.random(i));
db.patient.insert({"patid":patid,"patname":patname,"sex":sex,"age":age,address:{"city":"shanghai","street":"huaihai road"}});
}

MongoDB索引(Shell)

for(var i=0;i<100000;i++){
var patid="pat"+i;
var patname="name"+i;
var sex="M";
var age=parseInt(100*Math.random(i));
db.patient.insert({"patid":patid,"patname":patname,"sex":sex,"age":age});
}

#普通索引
db.patient.ensureIndex({"age":1})
#唯一索引
db.patient.ensureIndex({"patid":1},{"unique":true})
#复合索引
db.patient.ensureIndex({"patname":1,"age":1})

#解释执行计划
db.patient.find({"patid":"pat1000"}).explain();
db.patient.find({"age":99}).explain();
#指定索引进行查询
db.patient.find({"age":99}).hint({"patname":1,"age":1}).explain();

#枚举索引
db.patient.getIndexes();

#删除索引
db.patient.dropIndex("age_1");

MongoDB副本集(Shell)

0、原理
副本集原理

1、开启副本集节点

mongod --dbpath=D:\Database\MongoDB3\dbc0 --port=27017 --replSet neohope
mongod --dbpath=D:\Database\MongoDB3\dbc1 --port=27018 --replSet neohope
mongod --dbpath=D:\Database\MongoDB3\dbc2 --port=27019 --replSet neohope

2、初始化副本集

mongo --port 27017
config_rs={_id:'neohope',members:[{_id:0,host:'localhost:27017'},{_id:1,host:'localhost:27018'},{_id:2,host:'localhost:27019'}]}
rs.initiate(config_rs)
rs.status()

3、增加仲裁服务器

mongod --dbpath D:\Database\MongoDB3\dbc3 --port 27020 --replSet neohope/localhost:27017,localhost:27018,localhost:27019

4、设置仲裁服务器

mongo --port 27017
neohope:PRIMARY> rs.addArb("localhost:27020");
neohope:PRIMARY> rs.status()

5、将备用节点设为被动模式

neohope:PRIMARY> r=rs.conf()
neohope:PRIMARY> r.members[2].priority=0
neohope:PRIMARY> rs.reconfig(r)
neohope:PRIMARY> rs.status()