MongoDB详解
Posted 二宝小菜鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB详解相关的知识,希望对你有一定的参考价值。
一.概念阐述
1.什么是MongoDB?
MongoDB是文档型数据库, 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB文档类似于JSON对象,字段值可以包含其他文档,数组及文档数组。属于非关系型数据库(nosql),与传统关系型数据库有一些区别,是非关系数据库当中功能最丰富,最像关系型数据库的,是开源,高性能的NoSQL数据库,支持索引、集群、复制和故障转移、各种语言的驱动程序丰富。
2.什么是NoSql?
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
3.MongoDB特点
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。
MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,php,C#等多种语言。
一个mongodb中可以建立多个数据库。
MongoDB的默认数据库为"db",该数据库存储在data目录中
逻辑结构主要由数据库(database)、集合(collection)和文档(document)组成,一个数据库有多个集合,一个集合又有多个文档。
4.基本概念介绍
例如:
5.MongoDB支持的数据类型
Object ID :Documents自生成的 _id,用于创建文档的 ID,每个文档都有。
String:字符串,必须是utf-8
Boolean:布尔值,true 或者false (这里有坑哦~在Python中True False首字母大写)
Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)
Double:浮点数 (没有float类型,所有小数都是Double)
Arrays:用于将数组或列表或多个值存储为一个键。
Object:用于内嵌文档
Null:空数据类型 , 此类型用于存储NULL值。
Timestamp:时间戳。记录文档修改或添加的具体时间。
Binary Data:二进制数据。用于存储二进制数据。
Code:代码类型。用于在文档中存储 javascript 代码。
Regular expression:正则表达式类型。用于存储正则表达式。
Date:日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间,创建 Date 对象,传入年月日信息。
Symbol:符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
6.优缺点
(1)优点
文档结构的存储方式,并且它是有序的,能够更便捷的获取数据
在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能可以,同时它的写入性能也很厉害,可以写入百万级别的数据。
(2)缺点
MongoDB不支持事务操作,所以事务要求严格的系统,比如银行系统就不能用它。
MongoDB占用空间过大。
空间的预分配:当MongoDB的空间不足时它就会申请生成一大块硬盘空间,而且申请的量都是有64M、128M、256M来增加直到2G为单个文件的较大体积,并且随着数量叠增,可以在数据目录下看到整块生成而且不断递增的文件。
删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
7.常用使用场景
(1)缓存:由于性能很高,mongo也适合作为信息基础设施的缓存层。
(2)大尺寸、低价值的数据:比如存储一些日志文件。
(3)高伸缩性的场景:mongo非常适合由数十或者数百台服务器组成的数据库。
(4)用于对象及JSON数据的存储:mongo的BSON数据格式非常适合文档格式化的存储及查询。
8.数据库层命令
db.auth() 用户身份验证。
db.collection.stats() 查看文档的一些信息, 例如填充因子
coll = db.<collection> 将当前数据库中的特定集合设置为变量 coll,相当于取别名
例如:对myCollection使用变量执行操作,coll = db.myCollection,可以使用别名调用 coll.find()
db.collection.find() 查找集合中的所有文档并返回游标。
db.collection.insertOne() 将新文档插入集合中。
db.collection.insertMany() 将多个新文档插入集合中。
db.collection.updateOne() 更新集合中的单个现有文档。
db.collection.updateMany() 更新集合中的多个现有文档。
db.collection.save() 插入新文档或更新集合中的现有文档。
db.collection.deleteOne() 从集合中删除单个文档。
db.collection.deleteMany() 从集合中删除文档。
db.collection.drop() 完全删除或部分删除集合。
db.collection.remove() 完全删除或部分删除集合。
db.collection.createIndex() 如果索引不存在,则在集合上创建新索引; 否则,操作无效。
db.getSiblingDB() 使用此相同连接返回对另一个数据库的引用,而不显式切换当前数据库。这允许跨数据库查询。
语句比对:
二.项目的实战使用
1.需依赖的jar包
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.10.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.10.1</version>
</dependency>
2.连接方式介绍
(1)单纯连接MongoDB不需要验证,可以使用MongoClient来连接MongoDB,MongoClient的使用方式如下:
MongoClient mongoClient = new MongoClient("localhost", 27017);
DB db = mongoClient.getDB("mydb");
上面的代码连接了localhost:27017上MongoDB服务,并指定使用mydb数据库。连接后便可以对这个数据库作进一步的操作。
需要指出的是,MongoClient是线程安全的,可以在多程程环境中共享同一个MongoClient。通常来说,一个应用程序中,只需要生成一个全局的MongoClient实例,然后在程序的其他地方使用这个实例即可。
(2)连接需认证
下面介绍两种方式:
方式一:MongoCredential
MongoCredential类的createCredential方法可以指定认证的用户名,密码,以及使用的数据库,并返回一个MongoCredential对象。其方法的声明如下:
static MongoCredential createCredential(String userName, String database, char[] password)
例如:
MongoCredential credential = MongoCredential.createCredential("user", "mydb", "password".toCharArray();
上面创建了一个用户名为user,密码为password,数据库为mydb的MongoCredential对象。
将生成MongoCredential的对象作为MongoClient构造函数的参数。由于MongoClient构造函数的为List<MongoCredential>类型,所以需要先构造成一个List再传递。完整的认证的例子如下:
MongoCredential credential = MongoCredential.createCredential("user", "mydb", "password".toCharArray());
ServerAddress serverAddress = new ServerAddress("localhost", 27017);
MongoClient mongoClient = new MongoClient(serverAddress, Arrays.asList(credential));
DB db = mongoClient.getDB("mydb");
方式二:MongoClientURI
可以使用MongoClientURI完成MongoDB的认证,它代表了一个URI对象。MongoClientURI的构造函数接受一个String类型的字符串,这个字符串的格式如下:
mongodb://[username:password@]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/[database][?options]]
例如:
mongodb://test:password@200.29.200.206:8635,200.29.200.207:8635/demo?authSource=admin&replicaSet=replica
生成的MongoClientURI对象作为MongoClient构造函数的参数,完整的认证例子如下:
String sURI = String.format("mongodb://%s:%s@%s:%d/%s", "user", "password", "localhost", 27017, "mydb");
MongoClientURI uri = new MongoClientURI(sURI);
MongoClient mongoClient = new MongoClient(uri);
DB db = mongoClient.getDB("mydb");
一般需验证的话,都使用方式二,比较简单!!!
3.MongoDB工具类
package com.dogiant.demo.ws;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class MongoUtils {
private static MongoClient client;
private static final String DEFAULT_DB_NAME = "test";
static {
//这一步读取配置文件里的MongoDB地址
MongoClientURI clientURI = new MongoClientURI(SystemProperties.getValue("system.mongodb.clientUri"));
client = new MongoClient(clientURI);
}
/**
* 连接MongoDB的dbName数据库
* @param dbName
* @return
*/
public static MongoDatabase mongoDatabase(String dbName) {
return client.getDatabase(dbName);
}
/**
* 连接指定好的MongoDB数据库,并查询指定集合中的数据
* @param dbName
* @param collectionName
* @return
*/
public static MongoCollection<Document> getCollection(String dbName, String collectionName) {
return mongoDatabase(dbName).getCollection(collectionName);
}
/**
* 连接指定好的MongoDB数据库test
* @return
*/
public static MongoDatabase getDefaultDb() {
return mongoDatabase(DEFAULT_DB_NAME);
}
/**
* 连接指定好的MongoDB数据库test,并查询集合数据
* @return
*/
public static MongoCollection<Document> getCollection(String collectioName) {
return getDefaultDb().getCollection(collectioName);
}
}
4.使用样例
package com.dogiant.demo.ws;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.lt;
/**
* @author cbl
* @Description: TODO
* @date 2019/10/30 14:19
*/
public class MongoDBTest {
public void nsertTest(){
// 获取指定集合
MongoCollection<Document> collection = MongoUtils.getCollection("users");
// 创建需要插入的单个文档
Document doc = new Document("name", "MongoDB")
.append("type", "database")
.append("count", 1)
.append("versions", Arrays.asList("v3.2", "v3.0", "v2.6"))
.append("info", new Document("x", 203).append("y", 102));
//测试插入
collection.insertOne(doc);
// 测试插入多个文档
ArrayList<Document> documents = new ArrayList<Document>();
for (int i = 0; i < 100; i++) {
documents.add(new Document("i",i));
}
collection.insertMany(documents);
}
public void updateTest(){
// 获取指定集合
MongoCollection<Document> collection = MongoUtils.getCollection("users");
//update t_user set i = 110 where i = 10
//Bson filter = Filters.eq("i", 10);
//Document document = new Document("$set",new Document("i", 110));
//UpdateResult updateOne = collection.updateOne(filter, document);
UpdateResult updateResult = collection.updateOne(new Document("i", 10), new Document("$set", new Document("i", 110)));
// update t_user set i = 10 where i < 20
// lt(key,value) 静态导入 import static com.mongodb.client.model.Filters.lt;
collection.updateMany(lt("i",20),new Document("$set",new Document("i",10).append("test","test value")));
}
public void deleteTest(){
// 获取指定集合
MongoCollection<Document> collection = MongoUtils.getCollection("users");
//删除单个文档
Bson filterOne = Filters.eq("i",110);
DeleteResult deleteResultO =collection.deleteOne(filterOne);
DeleteResult deleteResultOne =collection.deleteOne(eq("i", 110));
//删除多个文档
Bson filterM = Filters.lt("i", 20);
DeleteResult deleteResult = collection.deleteMany(filterM);
//DeleteResult deleteResultM = collection.deleteMany(lt("i", 20));
System.out.println("删除的文档数:"+ deleteResult.getDeletedCount());
}
public void findTest(){
// 获取指定集合
MongoCollection<Document> collection = MongoUtils.getCollection("users");
//查找集合中的所有文档
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> iterator = findIterable.iterator();
while (iterator.hasNext()) {
//Document next = iterator.next();
//String json = next.toJson();
//JSONObject jsonObject = JSONObject.fromObject(json);
//installmentInfo.setPolicyNo(jsonObject.getString("policyNo"));
//installmentInfo.setPeriodNum(jsonObject.getString("periodNum"));
//installmentInfo.setCreatedDate(jsonObject.getString("createdDate"));
//installmentInfo.setInstallmentRequest(jsonObject.getString("installmentRequest"));
//list.add(installmentInfo);
System.out.println(iterator.next());
}
//查询指定条件文档
Bson filter = Filters.eq("name", "张三");
//指定查询过滤器查询
FindIterable<Document> iterable = collection.find(filter);
MongoCursor cursor = iterable.iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
//取出查询到的第一个文档
Document document = collection.find().first();
//打印输出
System.out.println(document);
}
}
总结,到这里,java对mongoDB的一些基本操作就介绍完了。实现的步骤为:添加驱动==>连接到服务==>连接到数据库==>选择集合==>对集合进行CRUD操作。
以上是关于MongoDB详解的主要内容,如果未能解决你的问题,请参考以下文章
14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段
ios - Heroku 和 MongoDb 上的自定义解析服务器错误 3080:JSON 文本没有以数组或对象开头,并且允许未设置片段的选项