介绍
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
说明:BSON是一种计算机数据交换格式,主要被用作MongoDB数据库中的数据存储和网络传输格式。 它是一种二进制表示形式。BSON之名缘于JSON,含义为Binary JSON(二进制JSON)。
特点:
1) 面向集合存储,易存储对象类型的数据
2) 支持动态查询
3) 支持完全索引,包含内部对象
4) 支持复制和故障恢复
5) 支持多种开发语言
6) 使用高效的二进制数据存储,包括大型对象(如视频等)
适用场景:
1)网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
2)缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。
3)高伸缩性的场景。非常适合由数十或数百台服务器组成的数据库,它的路线图中已经包含对MapReduce引擎的内置支持。
不适用的场景:
1)要求高度事务性的系统。
2)传统的商业智能应用。
3)复杂的跨文档(表)级联查询。
MongoDB支持的数据类型
1、null
null用于表示空值或不存在的字段。
{"x" : null}
2、布尔类型
布尔型数据有true和false两个值。
{"x" : true}
3、数值类型
默认使用64位浮点型数据。因此,会有以下两种数值形式:
{"x" : 2.32} 或 {"x" : 2}
对于整数类型,可以使用NumberInt()(位有符号整型)或NumberLong()(8位有符号整型)方法进行转换。示例如下:
{"x" : NumberInt(2)}
{"x" : NumberLong(2)}
4、字符串
{"x" : "123@qq.com"}
5、日期类型
MongoDB中日期使用时间戳表示,单位为毫秒,不存储时区
{"x" : new Date()}
6、数组
数据集可以用数组格式存储,与JavaSript中的数组表示相同
{"x" : ["vvvv", "77777"]}
7、内嵌文档
文档中可以嵌套一个子文档。建议使用子文档的形式组织数据,子文档查询效率要高于多键查询。
{"x" : {"name" : "vvv"}}
MongoDB与关系型数据库相比,最大的优势就是内嵌文档。与关系型数据库的扁平化数据结构相比,使用内嵌文档可以数据的组织方式更加自然。
8、_id和ObjectId
MongoDB中每个文档都有一个“id”键,“id”可以是任何类型,指定"_id"时MongoDB会生成一个ObjectId对象
{"_id" : ObjectId()}
常用指令
1、登录
>mongo ip地址 //默认端口号27017
注意:如果没有指定bind_ip,会导致mongodb默认绑定为127.0.0.1,导致外部无法访问修改mongodb.conf文件: bind_ip=0.0.0.0
2、退出
>exit
3、查看数据库
>show dbs
4、切换数据库
>use 数据库名
这个指令也可以直接创建数据库,但只有添加数据后,show dbs才能看到该数据库
5、查看当前数据库,默认数据库:test
>db
6、查看所有的数据集
>show collections
7、删除当前数据库
>db.dropDatabase()
8、创建集合(相当于创建表)
>db.createCollection("user1")
9、删除集合
>db.collectionName.drop()
10、集合重命名
>db.oldCollectionName.renameCollection("newName")
11、新增数据
>db.collectionName.insert({"key":value,"key":value})
或
>db.collectionName.save({"key":value,"key":value})
12、查询所有数据
>db.collectionName.find()
13、条件查询
find()以非结构化的方式展示文档
>db.collectionName.find({"age":26}) //查询等值关系
>db.collectionName.find({age : {$gt : 100}}) // 大于100
>db.collectionName.find({age : {$gte : 100}}) //大于等于100
>db.collectionName.find({age : {$lt : 150}}) //小于150
>db.collectionName.find({age : {$lte : 150}}) //小于等于150
>db.collectionName.find({age : {$lt :200, $gt : 100}}) //大于100,小于200
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法
>db.collectionName.find().pretty()
查询一条数据
>db.collectionName.findOne();
查询指定列
> db.collectionName.find({},{name:1,age:1,sex_orientation:true})
查询指定字段的数据,并去重
> db.collectionName.distinct('sex')
对结果集排序
> db.collectionName.find().sort({salary:1}) //升序
> db.collectionName.find().sort({salary:-1}) //降序
统计记录数
> db.collectionName.find().count()
查询限定条数
>db.collectionName.find().limit(number)
and 关系:MongoDB 的 fifind() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件
>db.collectionName.find({key1:value1, key2:value2}).pretty()
or关系:MongoDB OR 条件语句使用了关键字 $or
>db.collectionName.find({$or: [ {key1: value1}, {key2:value2}]}).pretty()
14、清空集合数据
>db.collectionName.remove({})
条件删除:remove({key:value})
删除满足条件的一条数据:remove({key:value},1)
15、更新数据
db.collectionName.update(<query>,<update>,{upsert: <boolean>, multi: <boolean>)
query: update的查询条件
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
示例:
> db.collectionName.update({name:'tom'},{$set:{age:23}},false,true)
Java连接MongoDB
添加jar包
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.2.2</version> </dependency>
public class Main {
@Test
public void fun(){
// 1.连接到 mongodb 服务
MongoClient mongoClient = new MongoClient("192.168.109.131", 27017);
// 2.连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
System.out.println(mongoDatabase);
//3.创建集合
mongoDatabase.createCollection("student");
// 获得集合
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
//4.新增
Document document = new Document("stu1name", "lisi");
document.append("stu1age", 29);
document.append("sex", "男");
collection.insertOne(document);
System.out.println("成功");
//插入多行时,将document对象添加到List集合中,调取insertMany()
//5.获得所有文档
FindIterable<Document> documents = collection.find();
MongoCursor<Document> iterator = documents.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//6.更新文档updateOne(),updateMany(条件表达式,新值表达式)
collection.updateMany(Filters.eq("sex","男"),new Document("$set",new Document("name","testzhangsan")));
// 7.删除文档
// 删除20岁用户的信息
collection.deleteOne(Filters.eq("stu1age",20));
}
}
MongoDB索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
创建索引的语法
>db.collection.createIndex(keys, options)
options取值的含义:
索引分类
1、默认索引
MongoDB有个默认的“id”的键,相当于“主键”的角色。集合创建后系统会自动创建一个索引在“id”键上,它是默认索引,索引名叫“_id_”,是无法被删除的。
可以通过>db.collectionName.getIndexes() 查看
2、单列索引
在单个键上创建的索引就是单列索引,例如我们要在Users集合上给title键创建一个单列索引,语法如下:
>db.collectionName.createIndex({"title":1}) (1表示正序,-1逆序)
3、组合索引
另外,我们还可以同时对多个键创建组合索引。如下代码创建了按照“UserId”正序,“UserName” 逆序的组合索引:
>db.collectionName.createIndex({"userid":1,"username":-1})
4、唯一索引
唯一索引限制了对当前键添加值时,不能添加重复的信息。值得注意的是,当文档不存在指定键时,会被认为键值是“null”,所以“null”也会被认为是重复的,所以一般被作为唯一索引的键,最好都要有键值对
>db.collectionName.CreateIndex({"UserId":1}, { unique: true });
5、TTL索引
TTL指生命周期的意思。即存储的document存储带有过期时间属性,超过生命周期自己主动删除。像日志数据、系统自己主动产生的暂时数据、会话数据等均符合这一场景。
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
删除索引
>db.collectionName.dropIndexes()
>db.collectionName.dropIndex("索引名称")
注意:drop()集合时,索引也会删除,remove()集合时,索引仍然存在