一、MongoDB 要点
1.MongoDB 特性:
1.模式自由,支持动态查询、完全索引
2.面向文档存储,易存储对象类型数据
3.高效的数据存储
4.支持复制和故障恢复,提供主从、主主模式的数据复制,服务器之间的复制
5.自动分片,支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器
2.MongoDB 工作方式:
1.介于关系数据库与非关系数据库之间
2.由database、collection、document三个层次
3.以单文档为单位存储
4.BSON (Binary SerializedDocument Notation)
5.使用了内存映射文件进行数据管理,把所有空闲内存当做缓存使用,且不能指定内存大小。优点:可以最大限度提升性能;缺点:容易受其他程序干扰。
6.数据空间采用预分配,避免形成过多硬盘碎片。为每一个数据库分配一系列文件,每个数据库会被分配一个大小,第一个文件名字为“.0”,大小为64M,第二个为“.1”,大小为128M,以此类推
7.“_id”字段为主键,自动生成ObjectId对象
8.每次插入BSON对象大小不超过4MB,超过4MB使用GridFS
9.删除记录不真正删除,只标记“已删除”,故删除不释放空间
3.MongoDB 主从服务启动
./mongod --master--port=11017 --dbpath=/data/db1 &
./mongod --slave--source=10.1.2.11:11017 --port=11018 --dbpath=/data/db2--slavedelay 5 &
从服务器只可读,不可写
4.MongoDB 分片
见书本,待补充
二、Java接口操作
1.连接集群
MongoClient mongoClient = new MongoClient(Arrays.asList(new ServerAddress("10.1.2.11", 27017),
new ServerAddress("10.1.2.12",27018),newServerAddress("10.1.2.12",27019)));
2.查找数据库
DB db = m.getDB( "mydb" );
3.验证用户名密码
boolean auth = db.authenticate(myUserName, myPassword);
4.查找集合
DBCollection bookCollection= db.getCollection("book");
5.插入
BasicDBObject doc =newBasicDBObject("name", "MongoDB").append("type", "database").append("count", 1).append("info", newBasicDBObject("x", 203).append("y", 102));
bookCollection.insert(doc);
6.查找
BasicDBObject query = new BasicDBObject("j", new BasicDBObject("$ne", 3).
append("k", new BasicDBObject("$gt", 10));Cursor cursor=coll.find(query);try{
while(cursor.hasNext()) {
System.out.println(cursor.next()); } } finally{
cursor.close();
}
7.索引
coll.createIndex(new BasicDBObject("i", 1)); // create index on "i", ascending
8.异常级别参数
转载自:http://blog.csdn.net/xinghebuluo/article/details/7035123
- WriteConcern.NONE:没有异常抛出
- WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常
- WriteConcern.SAFE:抛出网络错误异常、服务器错误异常;并等待服务器完成写操作。
- WriteConcern.MAJORITY: 抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作。
- WriteConcern.FSYNC_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘。
- WriteConcern.JOURNAL_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件。
- WriteConcern.REPLICAS_SAFE:抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作。
当我们执行如下操作时(将"name"为"lily"的"age"设置为20):
db.update({"name":"lily"},{"$set":{"age":20}})
默认情况下,该操作会使用WriteConcern.NORMAL(仅在网络错误时抛出异常),等同于:
db.update({"name":"lily"},{"$set":{"age":20}},WriteConcern.NORMAL)
使用NORMAL模式参数,可以使得写操作效率非常高。但是如果此时服务器出错,也不会返回错误给客户端,而客户端会误认为操作成功。
因此在很多重要写操作中需要使用WriteConcern.SAFE模式,保证可以感知到这个错误,保证客户端和服务器对一次操作的正确性认知保持一致。
9.集群读操作
ReadPreference.primary();
ReadPreference.primaryPreferred();
ReadPreference.secondary();
ReadPreference.secondaryPreferred();
ReadPreference.nearest();
- PRIMARY
-
The default read mode. Read from primary only. Throw an error ifprimary is unavailable. Cannot be combined with tags.
- PRIMARY PREFERRED
-
Read from primary if available, otherwise a secondary.
- SECONDARY
-
Read from a secondary node if available, otherwise error.
- SECONDARY PREFERRED
-
Read from a secondary if available, otherwise read from theprimary.
- NEAREST
-
Read from any member node from the set of nodes which respond thefastest. The responsiveness of a node is measured with pings. Anynode whose ping time is within 15 milliseconds of the node with thelowest ping time is considered near
三、数据操作
1.插入 insert
2.查找 query
db.user.find({'userid':11},{'name':1,'address':1})
前一个BSON表示查询条件,后一个BSON表示返回的列
大小比较 $gt, $lt, $gte, $lte,$ne
db.user.find({'_id':{'$gt':100,'lte':1000}})
数组元素范围,$all 全有
db.user.find({a:{$all:[1,2,3]}})
$in, 有一个
db.user.find({a:{$in:[1,2,3]}})
$nin, 没有
db.user.find({a:{$nin:[1,2,3]}})
存在某字段 $exists
db.user.find({"email":{$exists:true}})
或者$or
db.user.find({$or:[{'name':'haha'},{'id':555},{'grade':'100'}]})
全非 $nor
db.user.find({$nor:[{'name':'haha'},{'id':555},{'grade':'100'}]})
数组长度 $size
db.user.find({a:{$size:5}})
$where, 用于编写较复杂的自定义函数
$type , BSON类型
正则表达式
db.user.find({'name':${$regex:'u.*4$',$options:'i'}})
数目限制limit, 跳过skip
db.user.find.skip(5).limit(100)
排序 sort
db.user.find.sort({name:1,grade:-1});
分组group
db.user.group({
cond:{"country":"cn"},
key:{'city':true},
initial:{count:0,total_time:0},
reduce: function(doc,out){
out.count++;
out.total_time += doc.total_time;
},
finalize:function(out) {
out.avg_time= out.total_time/ out.count;
}
})
记录条数 count
唯一distinct
嵌套成员匹配 $elemMatch
执行计划 explain
游标
var cursor =db.user.find()
建立索引 ensureIndex
db.user.ensureIndex({name:1,grade:-1})
返回的记录数目范围 $slice
db.posts.find({},{comments:{$slice: 5}}) // 前5条评论
db.posts.find({},{comments:{$slice: -5}}) //后5条评论
db.posts.find({},{comments:{$slice: [20, 10]}}) // skip 20, limit10
db.posts.find({},{comments:{$slice: [-20, 10]}}) // 20 from end, limit10
3.更新 update
db.user.update({"name":"tom"},{$set:{'grade':100}},true,true)
参数1:查询条件
参数2:设置更新内容
参数3:是否若存在则更新,不存在新建
参数4:是否更新多条记录
$inc 数字增加
db.user.update({_id:1},{$inc:{age:1}})
$set 设置属性内容
$unset 删除属性
db.user.update({_id:1},{$unset:{email:1}})
$push 往数组添元素
$pop删除数组第一个元素
$pull 删除数组元素
$pullAll删除数组
$rename 重命名属性
db.user.update({_id:2},{$rename:{'aihao':'hobby'}})
$第一个匹配到的元素
db.user.update({x: 2}, {$inc: {"x.$":1}}, false, true);
4. save --存在则更新,不存在则创建
db.user.save({'_id':111,'name':'tom'})
和insert区别:insert若存在则抛异常
和update区别:参数个数不一样
5.添加用户
useadmin
db.addUser("theadmin","anadminpassword",false)
第三个表示是否只读
6.用户认证
db.auth("theadmin","anadminpassword")