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.基本概念介绍

MongoDB详解

例如:

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 {
@Test 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); }
@Test 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"))); }
@Test 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()); }
@Test 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详解的主要内容,如果未能解决你的问题,请参考以下文章

(转) Java中的负数及基本类型的转型详解

详解Android WebView加载html片段

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

MongoDB PHP

Python中verbaim标签使用详解

ios - Heroku 和 MongoDb 上的自定义解析服务器错误 3080:JSON 文本没有以数组或对象开头,并且允许未设置片段的选项