`

MongoDB初体验

阅读更多
昨天到今天,初步研究了一下MongoDB,主要是对照着这个系列文章自己实践了一遍:
http://www.cnblogs.com/huangxincheng/archive/2012/02/18/2356595.html

本文把这2天学到简要总结一下,按照自己的理解打乱了顺序。明天开始花2天时间通读一遍官方reference,再研究一下是否有方案能解决事务的问题,再找找有没有运维和可靠性方面的最佳实践

0、理解

感觉使用MongoDB的好处是:

性能较好,插入10万条数据只用了3秒钟;创建索引后的查询效率也很高
无schema,因此要增删字段都很容易,更容易实现一些对灵活性要求高的需求
很容易做复杂查询
内建的对master-slave和sharding的支持,使得做读写分离、分片都比较简单

缺点:

似乎不能回滚,误操作了怎么办?比如db.person.remove(),只能靠定期备份吗
好像也没有事务,怎么保证数据一致性?

1、基本概念

MongoDB里首先是分db,然后每个db下有collections,collection下保存文档

可以跟RDBMS对比一下,db的概念差不多,都是数据库实例;collections类似于table,但是没有schema;文档就是table里的一行记录

默认用mongo ip:port命令,会连上test db;如果用mongo ip:port/admin,则是连上admin db

用show dbs命令可以看到当前有哪些db。mongo的客户端同时也是一个javascript的执行环境,所以各db同时也是一个js object;用use [dbname]命令,可以切换db

创建db和创建collection,都不需要额外的命令(比如create table之类的),直接插入文档,就会生成db和collection,这点比较方便

mongod是server端的进程,mongos是做sharding时的server端进程;mongo是client,也是一个js执行环境。如果编程连接MongoDB,则driver就视为client

2、第一印象

第一次尝试这个命令
db.person.insert({name:"kyfxbl",age:29})

会觉得有点奇怪,不过只要理解了db.person是一个js object,insert是其上的一个方法,就很好理解了。事实上,如果输入db.person.insert,还会输出这个函数体。所以也可以这样
var single = {name:"kyfxbl",age:29} 
db.person.insert(single) 

值得一提的是,MongoDB用的是bson,跟json基本上是一回事,只是数据类型更多一点

3、条件查询

// where age = 20 
db.person.find({"age":20})


// where age > 20 
db.person.find({"age":{$gt:20}}) 


// where age >= 20 
db.person.find({"age":{$gte:20}}) 


// where age > 20 and favourite = "dota" 
db.person.find({"age":{$gt:20},"favourite":"dota"}) 


// where age < 20 or favourite = "dota" 
db.person.find({$or:[{"age":{$lt:20}},{"favourite":"dota"}]}) 


// where name in "zhengshengdong","kyfxbl" 
db.person.find({"name":{$in:["zhengshengdong","kyfxbl"]}}) 


// where name not in "zhengshengdong","kyfxbl" 
db.person.find({"name":{$nin:["zhengshengdong","kyfxbl"]}}) 


// find name startwith 'k' and endwith 'l' 
db.person.find({"name":/^k/,"name":/l$/}) 


// custom query function 
db.person.find({$where:function(){return this.age > 20}}) 
db.person.find({$where:function(){return this.name == "kyfxbl"}}) 

其中,$where绝对是个大招啊,非常强力。不过因为是大招,所以CD也长,不能随便乱放

4、update

// 更新的错误方法,这行记录会只剩下"age":20 
db.person.update({"name":"zhengshengdong"},{"age":20}) 


// 正确方法 
var condition = {"name":"zhengshengdong"} 
var model = db.person.findOne(condition) 
model.age = 20 
db.person.update(condition,model) 


// $inc和$set 
db.person.update({"name":"def"},{$inc:{"age":17}}) 
db.person.update({"name":"def"},{$set:{"age":23}}) 


// upsert 
db.person.update({"name":"liting"},{"age":100},true) 


// batch update 
db.person.update(condition,{$set:{"age":99}},false,true) 


5、聚合和游标

// group 
db.person.group({ 
key:{age:true}, 
initial:{}, 
reduce:function(cur,prev){}, 
finalize:function(out){}, 
condition:{} 
})


// cursor 
db.person.find().limit(2) 


6、索引

// 索引可以有效提升查询效率 
db.person.find({name:"zsd10000",age:10000}).explain() 
{ 
        "cursor" : "BasicCursor", 
        "isMultiKey" : false, 
        "n" : 1, 
        "nscannedObjects" : 100000, 
        "nscanned" : 100000, 
        "nscannedObjectsAllPlans" : 100000, 
        "nscannedAllPlans" : 100000, 
        "scanAndOrder" : false, 
        "indexOnly" : false, 
        "nYields" : 0, 
        "nChunkSkips" : 0, 
        "millis" : 54, 
        "indexBounds" : { 

        }, 
        "server" : "SZXY3Z001739121:27017" 
} 


db.person.find({name:"zsd10000",age:10000}).explain() 
{ 
        "cursor" : "BtreeCursor name_1", 
        "isMultiKey" : false, 
        "n" : 1, 
        "nscannedObjects" : 1, 
        "nscanned" : 1, 
        "nscannedObjectsAllPlans" : 2, 
        "nscannedAllPlans" : 2, 
        "scanAndOrder" : false, 
        "indexOnly" : false, 
        "nYields" : 0, 
        "nChunkSkips" : 0, 
        "millis" : 34, 
        "indexBounds" : { 
                "name" : [ 
                        [ 
                                "zsd10000", 
                                "zsd10000" 
                        ] 
                ] 
        }, 
        "server" : "SZXY3Z001739121:27017" 
} 


7、cluster

// 集群(主从集群和副本集)
mongod --dbpath=xxxx --master
mongod --dbpath=xxxx --port=8888 --slave --source=127.0.0.1:27017

mongo localhost:27017

db.person.insert({name:"yangliting",age:27})
not master

master负责写入,slave负责读取,不允许写入。slave从master定期同步文档和索引等

8、sharding

//mongo sharding
mongod --dbpath=..\db --port 2222
mongos --port 3333 --configdb=localhost:2222
mongod --dbpath=..\db --port 4444
mongod --dbpath=..\db --port 5555

mongo localhost:3333/admin
db.runCommand({addshard:"localhost:4444",allowLocal:true})
db.runCommand({addshard:"localhost:5555",allowLocal:true})
db.runCommand({enablesharding:"test"})
db.runCommand({shardcollection:"test.person",key:{name:1}}) // 自动在key上创建索引

use test
db.person.insert()
db.printShardingStatus()
分享到:
评论

相关推荐

    mongodb初体验

    mongodb初体验,mongodb初体验,mongodb初体验,mongodb初体验

    关于node.js初体验. 如何搭建并完成一个简单的后台, 配合mongodb数据库, 实现信息的增删改查功能

    关于node.js初体验. 如何搭建并完成一个简单的后台, 配合mongodb数据库, 实现信息的增删改查功能

    nosql 入门教程

    第2章 NoSQL上手初体验 17 2.1 第一印象——两个简单的例子 17 2.1.1 简单的位置偏好数据集 17 2.1.2 存储汽车品牌和型号数据 22 2.2 使用多种语言 30 2.2.1 MongoDB驱动 30 2.2.2 初识Thrift 33 2.3 小结 ...

    microscope:Discover Meteor书籍教程中的应用(作为代码完成)

    流星/ MongoDB find返回一个游标(这是一个React性数据源) 提取将光标转换为数组 注意:但是,Meteor应用程序可以在光标上进行迭代。 因此,当您明确想要数组中的数据时,将使用fetch 错误部分(validatePost) ...

    SpringCloudLearning_forezp.tar.gz

    史上最简单的SpringCloud教程 | 第十四篇: Spring Cloud Gateway初体验 史上最简单的SpringCloud教程 | 第十五篇: Spring Cloud Gateway 之Predict篇 史上最简单的SpringCloud教程 | 第十六篇: Spring Cloud Gateway...

    crails:Web应用程序的C ++ MVC开发的Crails框架

    Crails Framework是一个MVC Web开发框架,旨在为C ++开发人员带来类似Rails的体验。 尽管受到Ruby on Rails的启发,但它却轻巧得多。 它是基于cpp-netlib的HTTP服务器,使用路由系统,MVC设计,C ++编译的模板,...

    ThinkPHP v6.0.7

    内置了高性能的基于标签库和XML标签的编译型模板引擎RESTFul支持-通过REST控制器扩展提供了RESTFul支持,为你打造全新的URL设计和访问体验云平台支持-提供了对新浪SAE平台和百度BAE平台的强力支持,具备“横跨性”和...

    微服务架构和基于容器参考应用程序eShopOnContainers.zip

    这是一个很好的机会,来自社区的拉动请求,例如使用Nancy的新微服务,或者甚至其他语言,如Node,Go,Python或具有MongoDB Azure DocDB兼容性的数据容器,PostgreSQL,RavenDB,Event Store,MySql等。) 数据库...

Global site tag (gtag.js) - Google Analytics