码迷,mamicode.com
首页 > 数据库 > 详细

(转)MongoDB学习

时间:2018-12-10 13:59:46      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:访问   nat   base   update   故障恢复   完成后   ref   rhel7   ODB   

(二期)25、分布式文件存储数据库MongoDB

【课程25】mongod...命令.xmind96.9KB

【课程25】MongoD...概念.xmind0.5MB

【课程25】MongoDB简介.xmind93.8KB

【课程25】mongod...ysql.xmind0.3MB

【课程25】springb...godb.xmind79.2KB

【课程25预习】MongoDB.xmind0.1MB

 

官网

官网入门教程:https://university.mongodb.com/

中文社区:http://www.mongoing.com/

可视化客户端robomongo:https://robomongo.org/download

 

技术分享图片

百度百科

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

 

mongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

 

Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

特点

MongoDB适合存储一些关系简单、数据量又很大的数据。

 

它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

 

*面向集合存储,易存储对象类型的数据。

*模式自由。

*支持动态查询。

*支持完全索引,包含内部对象。

*支持查询。

*支持复制和故障恢复。

*使用高效的二进制数据存储,包括大型对象(如视频等)。

*自动处理碎片,以支持云计算层次的扩展性。

*支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。

*文件存储格式为BSON(一种JSON的扩展)。

*可通过网络访问。

 

最大缺点

  • 不支持事务,靠客户端自身保证
  • 新版本已经开始支持事务机制
场景使用
适用场景

1)网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

2)缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。

3)高伸缩性的场景。非常适合由数十或数百台服务器组成的数据库,它的路线图中已经包含对MapReduce引擎的内置支持。

不适用的场景

1)要求高度事务性的系统。

2)传统的商业智能应用。

3)复杂的跨文档(表)级联查询。

基本概念

不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库。

下面我们挨个介绍:

技术分享图片

直观用例:

技术分享图片

数据库

一个mongodb中可以建立多个数据库。

MongoDB的默认数据库为"db",该数据库存储在data目录中。

MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。

 

"show dbs" 命令可以显示所有数据的列表。

 

数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有‘ ‘(空格)、.、$、/、\和\0 (空字符)。
  • 应全部小写。
  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
文档

文档是一组键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

集合

集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。

 

集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

数据类型

一个MongoDB 实例可以包含一组数据库,一个DataBase 可以包含一组Collection(集合),一个集合可以包含一组Document(文档)。一个Document包含一组field(字段),每一个字段都是一个key/value pair。

key: 必须为字符串类型。

value:可以包含如下类型。

● 基本类型,例如,string,int,float,timestamp,binary 等类型。

● 一个document。

● 数组类型。

技术分享图片
数据关联

关系模型和文档模型的区别在哪里?

  • 关系模型需要你把一个数据对象,拆分成零部件,然后存到各个相应的表里,需要的是最后把它拼起来。举例子来说,假设我们要做一个CRM应用,那么要管理客户的基本信息,包括客户名字、地址、电话等。由于每个客户可能有多个电话,那么按照第三范式,我们会把电话号码用单独的一个表来存储,并在显示客户信息的时候通过关联把需要的信息取回来。
  • 而MongoDB的文档模式,与这个模式大不相同。由于我们的存储单位是一个文档,可以支持数组和嵌套文档,所以很多时候你直接用一个这样的文档就可以涵盖这个客户相关的所有个人信息。关系型数据库的关联功能不一定就是它的优势,而是它能够工作的必要条件。 而在MongoDB里面,利用富文档的性质,很多时候,关联是个伪需求,可以通过合理建模来避免做关联。

技术分享图片

文档模型优点:

  • 读写效率高-由于文档模型把相关数据集中在一块,在普通机械盘上读数据的时候不用花太多时间去定位磁头,因此在IO性能上有先天独厚的优势;
  • 可扩展能力强-关系型数据库很难做分布式的原因就是多节点海量数据关联有巨大的性能问题。如果不考虑关联,数据分区分库,水平扩展就比较简单;
  • 动态模式-文档模型支持可变的数据模式,不要求每个文档都具有完全相同的结构。对很多异构数据场景支持非常好;
  • 模型自然-文档模型最接近于我们熟悉的对象模型。从内存到存储,无需经过ORM的双向转换,性能上和理解上都很自然易懂。
MongoBD的安装

官网下载地址:(因为最新版本的配置有些不一样,所以这里介绍3.4版本的mongodb)

https://www.mongodb.org/dl/linux/x86_64-rhel70

技术分享图片

 

下载之后解压改名:

tar -zxvf mongodb-linux-x86_64-rhel70-v3.4-latest.tgz

mv mongodb-linux-x86_64-rhel70-v3.4 mongodb

技术分享图片

配置:

解压之后,创建data/db、logs目录分别用来存放数据和日志。

进入到bin目录下,编辑mongodb.conf文件,内容如下:

dbpath = /opt/mongodb/data/db #数据文件存放目录
logpath = /opt/mongodb/logs/mongodb.log #日志文件存放目录
port = 27017  #端口
fork = true  #以守护程序的方式启用,即在后台运行
nohttpinterface =true
bind_ip = 0.0.0.0 #默然只能127.0.0.1能够访问mongodb,如果远程的话可以设置指定ip,这里表示任何机器都可以访问

启动monogdb,使用./mongod -f mongodb.conf

技术分享图片

进入mongodb的控制台命令:./mongo,会输出当前的mongodb的版本号等信息。

技术分享图片

关闭服务

使用db.shutdownServer();命令可以关闭到MongoDB服务,但是这个命令的执行要在admin数据库下,所以先切换到admin,再关闭服务。退出之后,就进入不了了。

技术分享图片
数据库操作
创建数据库
use DATABASE_NAME

如果数据库不存在,则创建数据库,否则切换到指定数据库。

技术分享图片

我们刚创建的数据库 runoob 并不在数据库的列表中, 要显示它,我们需要向 runoob 数据库插入一些数据。

技术分享图片

删除数据库
db.dropDatabase()
创建账号授权

技术分享图片

集合操作
创建集合
db.createCollection(name, options)

参数说明:

  • name: 要创建的集合名称
  • options: 可选参数, 指定有关内存大小及索引的选项

options参数:

技术分享图片

截图:

技术分享图片

删除集合
db.collection.drop()
文档操作
创建文档

MongoDB 使用 insert() 或 save() 方法向集合中插入文档

#语法
db.COLLECTION_NAME.insert(document)

#实例
db.col.insert({title: ‘MongoDB 教程‘, 
    description: ‘MongoDB 是一个 Nosql 数据库‘,
    by: ‘菜鸟教程‘,
    url: ‘http://www.runoob.com‘,
    tags: [‘mongodb‘, ‘database‘, ‘NoSQL‘],
    likes: 100
})

以上实例中 col 是我们的集合名,如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档

 

查看已插入文档:

db.col.find()
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
> 
更新文档

update() 方法用于更新已存在的文档。语法格式如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

#实例
db.col.update({‘title‘:‘MongoDB 教程‘},{$set:{‘title‘:‘MongoDB‘}})

save() 方法通过传入的文档来替换已有文档,语法如下:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

#实例
db.col.save({
    "_id" : ObjectId("56064f89ade2f21f36b03136"),
    "title" : "MongoDB",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "Runoob",
    "url" : "http://www.runoob.com",
    "tags" : [
            "mongodb",
            "NoSQL"
    ],
    "likes" : 110
})

参数说明:

  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

更多实例

只更新第一条记录:

db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );

全部更新:

db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );

只添加第一条:

db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );

全部添加加进去:

db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

全部更新:

db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );

只更新第一条记录:

db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

删除文档

remove() 方法的基本语法格式如下所示:

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

#实例
db.col.remove({‘title‘:‘MongoDB 教程‘})

参数说明:

  • query :(可选)删除的文档的条件。
  • justOne : (可选)如果设为 true 或 1,则只删除一个文档。
  • writeConcern :(可选)抛出异常的级别。

说明

remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。

如删除集合下全部文档:

db.inventory.deleteMany({})

删除 status 等于 A 的全部文档:

db.inventory.deleteMany({ status : "A" })

删除 status 等于 D 的一个文档:

db.inventory.deleteOne( { status: "D" } )

 

常用关键字

$gt 大于

$lt 小于

$ne 不等于

$gte 大于或等于

$lte 小于或等于

$inc 可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。

$in 相当于T-SQL中的in

$nin 相当于T-SQL中的not in

 

db.b.update({"uid" : "20120002"},{"$inc":{"size" : 1}})

 

$set用来指定一个键并更新键值,若键不存在并创建。

db.a.update({"uid" : "20120002"},{"$set":{"size":10}})

 

$unset主要是用来删除键。

db.a.update({"uid" : "20120002"},{"$unset":{"sname":"abc"}})

 

$push向数组添加新的值。如果键值不存在,则创建一个。

db.c.update({"name" : "toyota"},{$push:{"title":"t1"}})

 

$addToSet主要给数组类型键值添加一个元素时,避免在数组中产生重复数据。

db.c.update({"name" : "toyota"},{$addToSet:{"title":"t2"}})

 

$pop从数组的头或者尾删除数组中的元素

db.c.update({"name" : "toyota"},{$pop:{"title":1}})

 

$pull从数组中删除满足条件的元素

db.c.update({"name" : "toyota"},{$pull:{"title":"t2"}})
与RDBMS相比
 

操作

格式

范例

RDBMS中的类似语句

等于

{<key>:<value>}

db.col.find({"by":"菜鸟教程"}).pretty()

where by = ‘菜鸟教程‘

小于

{<key>:{$lt:<value>}}

db.col.find({"likes":{$lt:50}}).pretty()

where likes < 50

小于或等于

{<key>:{$lte:<value>}}

db.col.find({"likes":{$lte:50}}).pretty()

where likes <= 50

大于

{<key>:{$gt:<value>}}

db.col.find({"likes":{$gt:50}}).pretty()

where likes > 50

大于或等于

{<key>:{$gte:<value>}}

db.col.find({"likes":{$gte:50}}).pretty()

where likes >= 50

不等于

{<key>:{$ne:<value>}}

db.col.find({"likes":{$ne:50}}).pretty()

where likes != 50

索引

createIndex()方法基本语法格式如下所示:

>db.collection.createIndex(keys, options)

#实例
db.col.createIndex({"title":1})

#复合索引
db.col.createIndex({"title":1,"description":-1})

createIndex() 接收可选参数,可选参数列表如下:

技术分享图片

常用命令

可参考文章:http://www.cnblogs.com/garinzhang/p/mongoDB_basic_usage.html

 

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"); 将指定机器上的数据库的数据克隆到当前数据库

 

6、从指定的机器上复制指定数据库数据到某个数据库

 db.copyDatabase("mydb", "temp", "127.0.0.1");将本机的mydb的数据复制到temp数据库中

 

7、修复当前数据库

 db.repairDatabase();

 

8、查看当前使用的数据库

 db.getName();

 db; dbgetName方法是一样的效果,都可以查询当前使用的数据库

 

9、显示当前db状态

 db.stats();

 

10、当前db版本

 db.version();

 

11、查看当前db的链接机器地址

 db.getMongo();

Collection聚集集合

1、创建一个聚集集合(table

 db.createCollection("collName", {size: 20, capped: 5, max: 100});

2、得到指定名称的聚集集合(table

 db.getCollection("account");

3、得到当前db的所有聚集集合

 db.getCollectionNames();

4、显示当前db所有聚集索引的状态

 db.printCollectionStats();

 

 用户相关

1、添加一个用户

 db.addUser("name");

 db.addUser("userName", "pwd123", true); 添加用户、设置密码、是否只读

2、数据库认证、安全模式

 db.auth("userName", "123123");

3显示当前所有用户

 show users;

4、删除用户

 db.removeUser("userName");

 

其他

1、查询之前的错误信息

 db.getPrevError();

2、清除错误记录

 db.resetError();

聚集集合查询

1、查询所有记录

db.userInfo.find();

相当于:select* from userInfo;

默认每页显示20条记录,当显示不下的情况下,可以用it迭代命令查询下一页数据。注意:键入it命令不能带";"

但是你可以设置每页显示数据的大小,用DBQuery.shellBatchSize= 50;这样每页就显示50条记录了。

  

2、查询去掉后的当前聚集集合中的某列的重复数据

db.userInfo.distinct("name");

会过滤掉name中的相同数据

相当于:select distict name from userInfo;

  

3、查询age = 22的记录

db.userInfo.find({"age": 22});

相当于: select * from userInfo where age = 22;

  

4、查询age > 22的记录

db.userInfo.find({age: {$gt: 22}});

相当于:select * from userInfo where age >22;

  

5、查询age < 22的记录

db.userInfo.find({age: {$lt: 22}});

相当于:select * from userInfo where age <22;

  

6、查询age >= 25的记录

db.userInfo.find({age: {$gte: 25}});

相当于:select * from userInfo where age >= 25;

  

7、查询age <= 25的记录

db.userInfo.find({age: {$lte: 25}});

  

8、查询age >= 23 并且 age <= 26

db.userInfo.find({age: {gte:23,lte: 26}});

  

9、查询name中包含 mongo的数据

db.userInfo.find({name: /mongo/});

//相当于%%

select * from userInfo where name like ‘%mongo%‘;

  

10、查询name中以mongo开头的

db.userInfo.find({name: /^mongo/});

select * from userInfo where name like ‘mongo%‘;

  

11、查询指定列name、age数据

db.userInfo.find({}, {name: 1, age: 1});

相当于:select name, age from userInfo;

当然name也可以用true或false,当用ture的情况下河name:1效果一样,如果用false就是排除name,显示name以外的列信息。

  

12、查询指定列name、age数据, age > 25

db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1});

相当于:select name, age from userInfo where age >25;

  

13、按照年龄排序

升序:db.userInfo.find().sort({age: 1});

降序:db.userInfo.find().sort({age: -1});

  

14、查询name = zhangsan, age = 22的数据

db.userInfo.find({name: ‘zhangsan‘, age: 22});

相当于:select * from userInfo where name = ‘zhangsan‘ and age = ‘22‘;

  

15、查询前5条数据

db.userInfo.find().limit(5);

相当于:selecttop 5 * from userInfo;

  

16、查询10条以后的数据

db.userInfo.find().skip(10);

相当于:select * from userInfo where id not in (

selecttop 10 * from userInfo

);

  

17、查询在5-10之间的数据

db.userInfo.find().limit(10).skip(5);

可用于分页,limit是pageSize,skip是第几页*pageSize

  

18、or与 查询

db.userInfo.find({$or: [{age: 22}, {age: 25}]});

相当于:select * from userInfo where age = 22 or age = 25;

  

19、查询第一条数据

db.userInfo.findOne();

相当于:selecttop 1 * from userInfo;

db.userInfo.find().limit(1);

  

20、查询某个结果集的记录条数

db.userInfo.find({age: {$gte: 25}}).count();

相当于:select count(*) from userInfo where age >= 20;

  

21、按照某列进行排序

db.userInfo.find({sex: {$exists: true}}).count();

相当于:select count(sex) from userInfo;

索引

1、创建索引

db.userInfo.ensureIndex({name: 1});

db.userInfo.ensureIndex({name: 1, ts: -1});

  

2、查询当前聚集集合所有索引

db.userInfo.getIndexes();

  

3、查看总索引记录大小

db.userInfo.totalIndexSize();

  

4、读取当前集合的所有index信息

db.users.reIndex();

  

5、删除指定索引

db.users.dropIndex("name_1");

  

6、删除所有索引索引

db.users.dropIndexes();

 修改、添加、删除集合数据

1、添加

db.users.save({name: ‘zhangsan‘, age: 25, sex: true});

添加的数据的数据列,没有固定,根据添加的数据为准

  

2、修改

db.users.update({age: 25}, {$set: {name: ‘changeName‘}}, false, true);

相当于:update users set name = ‘changeName‘ where age = 25;

  

db.users.update({name: ‘Lisi‘}, {$inc: {age: 50}}, false, true);

相当于:update users set age = age + 50 where name = ‘Lisi‘;

  

db.users.update({name: ‘Lisi‘}, {inc:age:50,set: {name: ‘hoho‘}}, false, true);

相当于:update users set age = age + 50, name = ‘hoho‘ where name = ‘Lisi‘;

  

3、删除

db.users.remove({age: 132});

  

4、查询修改删除

db.users.findAndModify({

query: {age: {$gte: 25}},

sort: {age: -1},

update: {set:name:′a2′,inc: {age: 2}},

remove: true

});

  

db.runCommand({ findandmodify : "users",

query: {age: {$gte: 25}},

sort: {age: -1},

update: {set:name:′a2′,inc: {age: 2}},

remove: true

});

修改器

文章:https://www.cnblogs.com/myrunning/p/5655615.html

 

$set修改器

$set 修改器用来指定一个键值。如果这个键不存在,则创建他,他对更新模式或者用户定义键来说非常方便。

 

$unset修改器

$unset修改用于将键删除

 

$inc修改器

$inc其用来增加或减少已有的键的键值,或者在键不存在的时候创建一个键。

 

数组修改器 $push

数组修改器,顾名思义它只可以用于操作数组,只能用在值为数组的键上。$push修改器如果指定的值已经存在,"$push"会想已有的数组末尾加入一个元素,要是没有就会创建一个新的数组。

 

数组修改器 $ne

$ne也是用来操作数组的修改器,在查询文档中,如果一个值不在数组里面就把他加进去,如果在不添加。

 

数组修改器 $addToSet

$addToSet也是用来操作数组的修改器,实现的功能与$ne修改器相同,且更为方便。使用$addToSet修改器可以避免重复。

 

数组修改器 $each

$each数组修改器要和$addToSet修改结合起来用,可以一次添加多个不同的值。例如上面的例子中,我们一次添加多个email值

 

数组修改器 $pop

$pop修改器主要于从数组中删除元素,他可以从数组中的任何一端删除元素

 

数组修改器 $pull

$pull修改器和$pop修改类似,都是用来删除数组中的元素

$pull可以基于特定条件来删除元素

$pull会将所有匹配到的数据全部删掉,如对数组[1,2,1,1]执行pull 1,得到的结果就是只有一个元素的数组[2]

 

数组的定位修改器 $

若是数组有多个值,而我们只想对其中一部分进行操作,有两种方法可以实现这种操作。

两种方法操作数组中的值:通过位置或定位操作符("$")

数组都是以0开头的,可以将下标直接作为键来选择元素。

分片

分片(sharding)是指将数据库拆分,将数据水平分散在不同的机器上的过程。

 

将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。

 

通过一个名为mongos的路由进程进行操作,mongos知道数据和片的对应关系(通过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差(+++里面的说明+++),查询则尽量避免跨分片查询。

 

使用分片的时机:

  • 1,机器的磁盘不够用了。使用分片解决磁盘空间的问题。
  • 2,单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
  • 3,想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。

读写均衡、去中心化

 

shard节点,

config server:存储元数据,讲数据路由到shard

mongos:介入前段请求,进行对应消息路由

 

分片

  • 提高并发性能
  • 水平化
  • 实现原理:数据打散分布
  • 维护成本:相对较高

副本级集群

  • 数据冗余、提高读性能
  • 中心化
  • 实现原理:数据镜像
  • 维护成本:相对容易
集群
  • 大多数原则:存活节点少于二分之一时候不会发生选举,并且会主节点会降级为只读
副本集数据同步的过程

副本集中数据同步的详细过程:Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败(只有当同步源的数据损坏或者数据与主节点不一致时才可能发生),则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。

 

springboot集成MongoDB

第一步:引入依赖

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-mongodb</artifactId>
      </dependency>

第二步:配置mongodb的链接信息

spring.data.mongodb.uri=mongodb://username:password@localhost:27017/itstyle

第三步:这时候环境配置已经配好,可以开始编码了。首先给实体添加注解。

@Id

主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束。如果自己不设置@Id主键,mongo会自动生成一个唯一主键,并且插入时效率远高于自己设置主键。

在实际业务中不建议自己设置主键,应交给mongo自己生成,自己可以设置一个业务id,如int型字段,用自己设置的业务id来维护相关联的表。

@Document

标注在实体类上,类似于hibernate的entity注解,标明由mongo来维护该表。

#把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。
@Document(collection="mongodb 对应 collection 名")    
@Indexed

声明该字段需要加索引,加索引后以该字段为条件检索将大大提高速度。 

  • 唯一索引的话是@Indexed(unique = true)。 

也可以对数组进行索引,如果被索引的列是数组时,MongoDB会索引这个数组中的每一个元素。 

也可以对整个Document进行索引,排序是预定义的按插入BSON数据的先后升序排列。 

@CompoundIndex

复合索引,加复合索引后通过复合索引字段查询将大大提高速度。

@Document
@CompoundIndexes({
    @CompoundIndex(name = "age_idx", def = "{‘lastName‘: 1, ‘age‘: -1}")
})
public class Person<T extends Address> {
}

写法如上,lastName和age将作为复合索引,数字参数指定索引的方向,1为正序,-1为倒序。方向对单键索引和随机存不要紧,但如果你要执行分组和排序操作的时候,它就非常重要了。

@Field

代表一个字段,可以不加,不加的话默认以参数名为列名。

@Transient

被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。

@DBRef

关联另一个document对象。类似于mysql的表关联,但并不一样,mongo不会做级联的操作。 

 

mongoTemplate--插入

//插入后id字段会被赋值,可以检查id是否为空来判断是否插入成功

mongoTemplate.insert(Object);

mongoTemplate--更新

Query query=new Query(Criteria.where("_id").is(id));

Update update = Update.update("要更新的字段", "更新的值");

mongoTemplate.updateFirst(query, update, Object.class);

mongoTemplate--删除

Query query=new Query(Criteria.where("_id").is(id));

mongoTemplate.remove(query,AutomaticAlarm.class);

mongoTemplate--查询
select fields from tableName where coditions order by field skip limit;

//查找所有

mongoTemplate.findAll(Object.class);

 

//分页查询

Query query = new Query();

query.skip("跳过的数据条数").limit("一页的数据条数");

return mongoTemplate.find(query, Object.class);

 

//条件查询1,多条件is("值")后面可以加and("字段2").is("值2")

Query query=new Query(Criteria.where("字段1").is("值1"));

return mongoTemplate.find(query, Object.class);

 

//条件查询2,gte大于 lte小于

Criteria criteria1 = Criteria.where("timestamp").gte(startTime).lte(endTime+1000);

实体
@Document(collection="users")
@CompoundIndexes({
    @CompoundIndex(name = "age_idx", def = "{‘name‘: 1, ‘age‘: -1}")
})
public class MongoUser implements Serializable {

   private String grade;//从mongo中读取数据的系统业务需要 但在数据库中并不存在于user表中或此列是由逻辑计算得来

   //user实体的属性
   @Id
   private String uid;

   private String name;
   private int age;

   @Transient
   private String address;

   @DBRef
   private MongoClazz clazz;
服务类

使用MongoTemplate 来操作数据

构造函数

     Query (Criteria criteria)

     接受的参数是org.springframework.data.mongodb.core.query.Criteria

 

Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。

    例如: 查询条件onumber="002"

    mongoTemplate.find (new Query(Criteria.where("onumber").is("002")),entityClass)

 

例如:onumber="002" and cname="zcy"     

     mongoTemplate.find (new Query(Criteria.where("onumber").is("002").and("cname").is("zcy")),entityClass)

 

 

例如:onumber="002" or cname="zcy"

        mongoTemplate.findOne(newQuery(newCriteria().orOperator(Criteria.where("onumber").is("002"),Criteria.where("cname").is("zcy"))),entityClass); 

技术分享图片

 

 

@Component("userService")
public class MongoUserServiceImpl implements MongoUserService {

    @Autowired
    MongoTemplate mongoTemplate;
    
    public void saveUser(MongoUser users) {
        mongoTemplate.save(users);
    }

    public MongoUser findUserByName(String name) {
        return mongoTemplate.findOne(
                new Query(Criteria.where("name").is(name)), MongoUser.class);
    }
}

 

(转)MongoDB学习

标签:访问   nat   base   update   故障恢复   完成后   ref   rhel7   ODB   

原文地址:https://www.cnblogs.com/free-wings/p/10095720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!