MongoDB学习总结(二)

前言:学习札记!

MongoDB学习总结(二)

1.  安装、初识

之前写过一篇MongoDB的快速上手文章,里边详细的讲了如何安装、启动MongoDB,这里就不再累述安装过程,简单介绍一下Mongodb的基本操作。

打开命令行窗口,输入“mongo”命令,默认会连接到test数据库。

l  Insert

db.person.insert({"name":"Olive","age":18})

db.person.insert({"name":"Momo","age":17})

l  find

db.person.find()//查找所有的person数据

{ "_id" :ObjectId("58a03991d57e6773c574e485"), "name" :"Olive", "age" : 18 }

{ "_id" :ObjectId("58a039a8d57e6773c574e486"), "name" :"Momo", "age" : 17 }

db.person.find({"name":"Olive"})//查找名为Olive的person数据

{ "_id" :ObjectId("58a03991d57e6773c574e485"), "name" :"Olive", "age" : 18 }

u  "$gt","$gte", "$lt", "$lte", "$ne", "没有特殊关键字"(对应的为>,>=,<,<=,!=)

db.user.find({"age":{$gt:22}})//年龄大于22

{ "_id" : ObjectId("58a03dc7d57e6773c574e488"),"name" : "joe", "password" : "123456","age" : 25, "address" : { "province" :"henan", "city" : "zhengzhou" },"favourite" : [ "money", "girl" ] }

db.user.find({"age":{$lt:22}})//年龄小于22

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

db.user.find({"age":{$ne:25}})//年龄不等于25

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

u  "无关键字“, "$or", "$in","$nin"

db.user.find({$or:[{"name":"jack"},{"age":25}]})//名字为jack或age为25的user

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }

db.user.find({"address.city":{$in:["chaoyang","zhengzhou"]}})//城市为chaoyang或zhengzhou的user

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }

db.user.find({"address.city":{$nin:["chaoyang1","zhengzhou"]}})//查找城市不是chaoyang1或不是zhengzhou的user

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

u  正则表达式匹配

db.user.find({$or:[{"name":/^j/},{"name":/e$/}]})//匹配名字以j开头或者名字以e结尾的user

{ "_id" :ObjectId("58a03cc0d57e6773c574e487"), "name" :"jack", "password" : "123456", "age" :20, "address" : { "province" : "beijing","city" : "chaoyang" }, "favourite" : ["apple", "banana" ] }

{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }

u  $where

db.user.find({$where:function(){return this.name=="joe"}})//用$where的方式查询名为joe的user

{ "_id" :ObjectId("58a03dc7d57e6773c574e488"), "name" :"joe", "password" : "123456", "age" :25, "address" : { "province" : "henan","city" : "zhengzhou" }, "favourite" : ["money", "girl" ] }

l  Update

db.person.update({"name":"Olive"},{"name":"Olive116","age":19})//更新名为Olive的person信息

u  $inc 修改器(自增$inc指定的值,如果“文档”中没有此key,则会创建key,局部修改)

db.user.update({"name":"jack"},{$inc:{"age":10}})

u  $set修改器(局部修改age值)

db.user.update({"name":"jack"},{$set:{"age":10}})

u upsert操作(如果没有查到,就在数据库里面新增一条)

db.user.update({"name":"jackson"},{$inc:{"age":1}},true)//更新名为jackson的age值,如果该user不存在,则新增一条user信息

u  批量更新

db.user.update({“name”:“hxf”},{$inc:{“age”:10}},true)//批量更新名为hxf的user

l  remove

db.person.remove({"name":"Momo"})//移除名为Momo的person信息

2.  聚合

2.1count

db.user.count({"age":25})//统计age为25的user个数

2.2distinct

db.user.distinct("age")

2.3group

db.user.group({"key":{"age":true},"initial":{"person":[]},"$reduce":function(cur,prev){prev.person.push(cur.name);}})

key:  这个就是分组的key,我们这里是对年龄分组。

initial: 每组都分享一个”初始化函数“,特别注意:是每一组,比如这个的age=20的value的list分享一个initial函数,age=22同样也分享一个initial函数。

$reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象,第一次为initial中的{”perosn“:[]}。有多少个文档, $reduce就会调用多少次。

结果:

[

{

"age" : 10,

"person" : [

"jack"

]

},

{

"age" : 25,

"person" : [

"joe"

]

},

{

"age" : 1,

"person" : [

"jackson"

]

}

]

db.user.group({"key":{"age":true},"initial":{"person":[]},"reduce":function(doc,out){out.person.push(doc.name);},"finallize":function(out){out.count=out.person.length;},"condition":{"age":{$lt:25}}})

user数组里面的人员太多,想加上一个count属性标明一下。

针对上面的需求,在group里面还是很好办到的,因为group有这么两个可选参数: condition 和 finalize。

condition:  这个就是过滤条件。

finalize:这是个函数,每一组文档执行完后,多会触发此方法

结果:

[

{

"age" : 10,

"person" : [

"jack"

]

},

{

"age" : 1,

"person" : [

"jackson"

]

}

]

2.4mapReduce

mapReduce其实是一种编程模型,用在分布式计算中,其中有一个“map”函数,一个”reduce“函数。

l  map:

这个称为映射函数,里面会调用emit(key,value),集合会按照你指定的key进行映射分组。

l  reduce:

这个称为简化函数,会对map分组后的数据进行分组简化,注意:在reduce(key,value)中的key就是

emit中的key,vlaue为emit分组后的emit(value)的集合,这里也就是很多{"count":1}的数组。

l  mapReduce:

这个就是最后执行的函数,参数为map,reduce和一些可选参数

mapfunction(){ emit(this.name,{count:1});

reducefunction(key,value){ var result={count:0}; for(var i=0;i<value.length;i++){result.count+=value[i].count;}return result;}

db.user.mapReduce(map,reduce,{“output”:“collection”});

3.  游标

Mongodb里的游标是申明一个查询结构,并没有出具体的数据,只有在遍历时才加载过来,通过游标读取,枚举完成之后销毁游标。

Varlist=db.user.find()

list.Foreach(function(item){print(item.name);});

同时在构造查询时,还可以根据需要进行复杂的查询构造,例如:分页、排序等

Varlist=db.user.find().sort({“name”,1}).skip(3).limit(3);

4.  索引

4.1 性能分析函数(explain)

在数据库中插入10万条数据,如下:

for(vari=0;i<1000000;i++) {

...var rand=parseInt(i*Math.random());

...db.user.insert({"name":"HXF"+i,"age":i})

... }

查找一条数据,并利用“explain”分析函数,进行查询分析。

db.user.find({"name":"HXF9999"}).explain()

{

"queryPlanner" : {

"plannerVersion" : 1,

"namespace" :"test.user",

"indexFilterSet" :false,

"parsedQuery" : {

"name" : {

"$eq": "HXF9999"

}

},

"winningPlan" : {

"stage" :"COLLSCAN",

"filter" : {

"name" : {

"$eq" : "HXF9999"

}

},

"direction" :"forward"

},

"rejectedPlans" : [ ]

},

"serverInfo" : {

"host" :"WIN-GJ07N56QAK7",

"port" : 27017,

"version" :"3.0.6",

"gitVersion" :"1ef45a23a4c5e3480ac919b28afcba3c615488f2"

},

"ok" : 1

}

4.2 建立索引(ensureIndex)

db.user.ensureIndex({“name”:1});

利用ensureIndex方法为name字段添加索引,“1”表示照name升序,“-1”表示照name降序。

db.user.find({name:“墨遥”}).explain();

4.3 唯一索引

db.user.ensureIndex({"name":1},{"unique":true})

创建唯一索引,重复的键就不能再插入。

4.4 组合索引

多条件查询时,可以通过创建组合索引来加速查询。

db.user.ensureIndex({"name":1,"birthday":1})

创建组合索引,按照name升序,birthday升序。升序和降序的不同都会产生不同的索引。

我们可以通过getindexes来查看user下创建的所有索引。

db.user.getIndexes();

查询优化器在做查询时,会使用我们建立的这些索引来创建查询方案,如果某一个先执行完则其他查询方案被close掉,这种方案会被mongodb保存起来,当然如果非要用自己指定的查询方案,这也是可以的,在mongodb中给我们提供了hint方法让我们可以暴力执行。

db.user.find({name:‘HXF’,age:27}).hint({age:1,name:1});

4.5 删除索引

db.user.dropIndex(“name_1”)

5.  主从复制

Mongodb主从复制的部署架构可以实现数据的备份、数据恢复、读写分离。

部署实践:

在一台服务器上启动Mongodb并将该数据库指定为主数据库,命令如下:

mongod --dbpath D:\MangoDB\Data –master

在另一台服务器上启动mongodb并将该数据库指定为从数据库,命令如下:

mongod –dbpath E:\MongoDB\Data –-slave –source=主服务器IP:27017

动态的添加从属服务器:

在新增的mongodb服务器上,使用local数据库,并在sources中添加一个host

地址,如下:

在新的mongodb服务器上启动mongodb数据库,

use local

db.sources.insert({“host”:”主服务器Ip:端口”});//127.0.0.1:27017

l  读写分离

在从属服务器中,执行rs.slaveOk()即可支持从从属数据库读取信息

6.  副本集

副本集也是属于主从集群,但是跟上边的集群有区别的。

l  副本集的集群没有特定的主数据库

l  如果某个主数据库宕机了,集群会自动推选一个从属数据库作为主数据库顶上,具备了自动故障恢复功能。

实践如下:

创建集群,启动D盘的mongodb程序,指定端口2222,,其中集群的名字为HXFX,--replSet表示告知服务器HXFX集群下还有其他的数据库(即指定的端口3333的数据库)

mongod--dbpath D:\MongoDB\Data --port 2222 --replSet HXFX/127.0.0.1:3333

打开端口为3333的数据库

mongod--dbpath D:\SubMongoDB\Data --port 3333 --replSet HXFX/127.0.0.1:2222

连接到任意一台服务器,并以admin登录数据库,进行副本集的初始化,命令如下:

mongo127.0.0.1:2222/admin

rs.runCommand({"replSetInitiate":{"_id":"HXFX"},"members":[{"_id":1,"host":"127.0.0.1:2222"},{"_id":2,"host":"127.0.0.1:3333"}]}})

新增一台服务器,作为仲裁服务器,如下:

mongod--dbpath D:\ThreeMongoDB\Data --port 4444 --replSet HXFX/127.0.0.3:2222

然后我们在admin集合中使用rs.addArb()追加即可。如下:

rs.addArb("127.0.0.1:4444")

7.  分片

当数据量达到T级别的时候,mongodb采用将集合进行拆分,将拆分的数据分摊到几个片上。我们要了解”片键“的概念,也就是说拆分集合的依据是,按照键值进行拆分集合。这里需要一个路由服务器(mongos),根据管理员设置的“片键”将数据分摊到自己管理的mongod集群,同时需要一个config服务器,用来保存数据和片的对应关系以及相应的配置信息。同时还需要若干的mongodb服务器。具体实践如下:

7.1 开启config服务器

Config服务主要用来存储数据和片的对应关系,所应该最先开启。

--开启Config服务器

mongod --dbpath D:\SubMongoDB\Data --port 2222

7.2 开启mongos服务器

Mongos服务器就是一个路由服务器,同时要为其指定config服务器

--开启mongos服务器

mongos --port 3333 --configdb 127.0.0.1:2222

7.3 添加mongodb服务器(也就是要添加的片)

--启动mongod服务器(4444,5555)

mongod --dbpath D:\ThreeMongoDB\Data --port 4444

mongod --dbpath D:\FourMongoDB\Data --port 5555

7.4 连接到mongos服务器并将mongodb服务添加分片

--连接到mongods服务器并将(4444,5555)服务器添加分片

mongo 127.0.0.1:3333/admin

db.runCommand({"addshard":"127.0.0.1:4444",allowLocal:true})

db.runCommand({"addshard":"127.0.0.1:5555",allowLocal:true})

7.5 mongos服务器设置片键切分数据

--开启数据库的分片功能

mongo 127.0.0.1:3333/admin

db.runCommand({"enablesharding":"test"})—为test数据开启分片功能

--指定集合中分片的键

db.runCommand({"shardcollection":"test.user","key":{"name":1}})—指定test数据库中user集合的name为片键

7.6 插入数据,查看效果

通过mongos向mongodb中插入10w数据,并通过db.printShardingStatus()来查看效果

插入的1万条数据分布在4444和5555服务器上。

8.  安装部署

Mongod –dbpath D:\MongoDB\Data –-logpath D:\MongoDB\Log\log.txt–port 2222 –install

设置MongoDB数据存储路径,日志路径,同时开启了安装服务寄宿。

9.  状态监控

通过db.serverStatus()来查看服务器的统计信息(全局锁、索引、用户操作行为等)

通过mongostat实时刷新,观看数据实时变化。

Mongostat –port 3333

10.          安全认证

Use admin

Db.system.users.remove({“user”:”XXX”})

11.          备份和恢复

Mongodump和mongorestore内置工具,保证不关闭服务器仍能copy数据。使用如下:

Mongodump -–port2222 –d test –o D:\MongoDB\Backup

将test数据库备份到D盘的mongoDB文件夹下的Backup文件夹下

Mongorestore–-port 2222 –d test –-drop  D:\MongoDB\Backup\test

将D:\MongoDB\Backup\test还原到test数据库,并删除备份文件

通过加锁和释放锁的方式保证数据,能够全部的备份下来

db.runCommand({"fsync":1,"lock":1})

释放锁: db.$cmd.unlock.findOne()

12.          驱动示例

官网驱动示例:(从官网下载Mongodb.net 的驱动)

App.config内容:

<configuration>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>

</startup>

<appSettings><!—配置连接字符串、数据库-->

<add key="ConnString" value="mongodb://127.0.0.1:27017"/>

<add key="DataBase" value="HXFDB"/>

</appSettings>

</configuration>

public staticclass MongoDBFactory

{

privatestatic string conn = ConfigurationManager.AppSettings["ConnString"];

privatestatic string database = ConfigurationManager.AppSettings["DataBase"];

private static MongoClient client = new MongoClient(conn);

privatestatic MongoServer server = client.GetServer();

privatestatic MongoDatabase db = server.GetDatabase(database);

//增

public static void Insert(string name)

{

MongoCollection collection = db.GetCollection("User");

User user = new User() { ID = 0, Name = name, Sex = "男", Age = 27, Code = "MY001" , _id=newBson.ObjectId()};

collection.Insert<User>(user);

QueryDocument query = new QueryDocument { { "Name", name } };

var list = collection.FindAs<User>(query);

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

}

//改

publicstatic void Update1(string name)

{

MongoCollection collection = db.GetCollection("User");

QueryDocument query = new QueryDocument { {"Name",name}};

IMongoUpdate update = Update.Set("Code", "Olive001");

collection.Update(query,update);

var list = collection.FindAllAs<User>();

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

}

//删

publicstatic void Remove(string name)

{

MongoCollection collection = db.GetCollection("User");

QueryDocument query = new QueryDocument { { "Name", name } };

collection.Remove(query);

var list = collection.FindAllAs<User>();

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

}

//查

publicstatic void Query()

{

MongoCollection collection = db.GetCollection("User");

Console.WriteLine("SELECT * FROM table ");

//SELECT * FROM table

var list = collection.FindAllAs<User>();

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

Console.WriteLine("SELECT * FROM table WHERE Uid > 10 AND Uid< 20");

// sql : SELECT * FROM table WHERE Uid > 10 AND Uid < 20

QueryDocument query = new QueryDocument { };

BsonDocument bd=new BsonDocument ();

bd.Add("$gte",0);

bd.Add("$lt",5);

query.Add("ID", bd);

list = collection.FindAs<User>(query);

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

Console.WriteLine("SELECT Name FROM table WHERE Uid > 10 AND Uid< 20");

// SELECT Name FROM table WHERE Uid > 10 AND Uid < 20

FieldsDocument f = new FieldsDocument();

f.Add("Name", 1);

list = collection.FindAs<User>(query).SetFields(f);

foreach (var u in list)

{

Console.WriteLine("Name: {0}", u.Name);

}

Console.WriteLine("SELECT * FROM table ORDER BY Uid DESC LIMIT10,10");

//SELECT * FROM table ORDER BY Name DESC LIMIT 10,10

SortByDocument s = new SortByDocument();

s.Add("Name", -1);

list = collection.FindAs<User>(query).SetSortOrder(s).SetSkip(1).SetLimit(10);

foreach (var u in list)

{

Console.WriteLine("Name: {0}, Sex: {1}, Age: {2}, Code: {3}", u.Name,u.Sex, u.Age, u.Code);

}

}

}

}

时间: 2024-10-19 12:55:46

MongoDB学习总结(二)的相关文章

angularjs+express4+mongodb学习【二】

这阶段,工作比较不忙,在学习angularjs+express4+mongodb,上周搭建了express4+angularjs 11.10 ===============mongodb的学习 mongodbwindows数据库cmdservice 1.下载mongodb的windows版本,有32位和64位版本,根据系统情况下载,下载地址:http://www.mongodb.org/downloads 2.解压缩至E:/mongodb即可 3.创建数据库文件的存放位置,比如E:/mongod

MongoDB学习(二):数据类型和基本概念

本文地址: http://www.cnblogs.com/egger/archive/2013/04/27/3047191.html 欢迎转载 ,请保留此链接??? ????! 数据类型 基本数据类型 MongoDB的文件存储格式为BSON,同JSON一样支持往其它文档对象和数组中再插入文档对象和数组,同时扩展了JSON的数据类型.与数据库打交道的那些应用.例如,JSON没有日期类型,这会使得处理本来简单的日期问题变得非常繁琐.只有一种数字类型,没法区分浮点数和整数,更不能区分32位和64位数字

MongoDB 学习(二)可视化界面

一.安装可视化界面 1.mongobooster 安装和配置 1.下载安装 下载地址:https://nosqlbooster.com/downloads 下载完成后直接点击安装: 安装完成弹出界面: 2.点击 create 创建链接: 3.点击 Test Connection 测试链接: 4.测试 OK 后 点击 Save & Connect 链接到本地数据库: 2.在 mongobooster 中写操作语句 1.查看集合 2.新增一条数据 3.修改一条数据 4.查看文档 二.在 Java 中

MongoDB学习笔记二:创建、更新及删除文档

插入并保存文档 对目标集使用insert方法插入一个文档: > db.foo.insert({"bar" : "baz"}) 这个操作会给文档增加一个"_id"键(要是原来没有的话),然后将其保存到MongoDB中.批量插入 如果要插入多个文档,使用批量插入会快一些.批量插入传递一个由文档构成的数组给数据库.如果只是导入数据(例如,从数据feed或者MySQL中导入),可以使用命令行工具,如mongoimport,而不是使用批量插入. 删除

Mongodb学习笔记二(Mongodb基本命令)

一.Mongodb命令 说明:Mongodb命令是区分大小写的,使用的命名规则是驼峰命名法. 对于database和collection无需主动创建,在插入数据时,如果database和collection不存在则会自动创建. 常用命令 help命令通过此命令可以看到一些最基本的命令,如图: use命令例如命令[use demodb],创建demodb,不用担心demodb不会创建,当使用use demodb 命令创建第一个collection时会自动创建数据库demodb,如图: 插入数据使用

mongoDB学习(二)之常用的修改操作

插入文档(插入数据库) db.person.insert({_id:"0001",name"yuexin"}) 清除数据 db.person.drop() 批量插入文档 shell中不支持批量插入 完成批量插入使用for循环 for(var i=0;i<10;i++){ .. db.persons.insert({_id:i,name:"yuexin"+i}) .. } save操作 save操作与insert操作的区别是当id一样的时候s

MongoDB学习(二)mongoDB常用命令

一.DB 数据操作 (1) Help查看命令提示 help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.help(); (2) 切换/创建数据库 use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库 (3) 查询所有数据库 show dbs; (4) 删除当前使用数据库 db.dropDatabase(); (5) 从指定主机上克隆数据库 db.cloneDatabase("127.0.0.1&

MongoDB学习笔记&lt;二&gt;

继续刚才的shell的学习,又继续学了如下知识: --文档数据插入 --文档数据删除 --文档数据更新 具体如下: 1.插入文档 db.person.insert({"name":"xiaoming"}) 2.批量插入 使用for循环来做,比如: for(var i=0;i<10;i++){ db.person.insert({"name":i}) } 3.save操作 和insert操作类似,save操作和insert操作的区别在于:如果

MongoDB 学习笔记二:安装MongoDB

1.下载MongoDB MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mongodb.com/download-center#community.注意:在 MongoDB 2.2 版本后已经不再支持 Windows XP 系统.最新版本也已经没有了 32 位系统的安装文件. 2.安装MongoDB 我下载的是mongodb-win32-x86_64-2008plus-ss

MongoDB学习笔记(二)

Mongo命令和配置1.启动项 1 --dbpath 指定数据库的目录 2 --port 端口 默认是27017 3 --fork 以后台守护的方式进行启动 4 --logpath 制定日志文件输出路径 5 --config 指定一个配置文件 6 --auth 以安全的方式启动数据库 7 --rest 会启动一个帮助页面 2.关闭数据库 db.shutdownServer(); 3.导入导出 - 导出 mongoexport -d 指定导出的数据库 -c 制定导出的集合 -o 导出的文件路径 -