精华内容
下载资源
问答
  • mongodb实验报告 介绍 我使用Dropwizard,MongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的,作为将计数器发送到MongoDB(或任何其他DB)的缓冲区。 我也想尝试MondleDB插件的Gradle...

    mongodb实验报告

    介绍

    我使用Dropwizard,MongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的,作为将计数器发送到MongoDB(或任何其他DB)的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来,我想创建某种界面来检查此框架,因此我决定尝试使用DropWizard。 这就是这个项目的创建方式。

    本文不是使用任何选定技术的教程。 这是一个小展示柜,我做过实验。 我猜有一些缺陷,也许我没有使用所有“最佳实践”。 但是,我确实相信,在本文的帮助下,该项目可以成为我使用的各种技术的良好起点。 我还尝试显示一些设计选择,这些选择有助于实现SRP,去耦,内聚等。

    我决定从用例描述及其实现方式开始。 之后,我将解释我对Gradle,MongoDB(和嵌入式)和Dropwizard所做的工作。

    在开始之前,这里是源代码:

    用例:带缓冲区的计数器

    我们对服务器有一些输入请求。 在请求过程中,我们选择用一些数据(由某些逻辑决定)“绘制”它。 有些请求将由Value-1绘制,某些请求将由Value-2绘制,等等。有些将根本不会绘制。 我们要限制绘画请求的数量(每个绘画值)。 为了有限制,对于每个绘制值,我们知道最大值,但是还需要计算(每个绘制值)绘制请求的数量。 由于系统具有多个服务器,因此计数器应由所有服务器共享。

    延迟至关重要。 通常,每个请求处理会得到4-5毫秒(对于所有流程。不仅仅是绘画)。 因此,我们不希望增加计数器会增加延迟。 相反,我们将保留一个缓冲区,客户端将向缓冲区发送“增加”。 缓冲区将定期以“批量增量”增加存储库。

    我知道可以直接使用Hazelcast或Couchbase或其他类似的快速内存数据库。 但是对于我们的用例,那是最好的解决方案。

    原理很简单:

    • 从属模块将调用服务以增加某个密钥的计数器
    • 该实现为每个键保留一个计数器缓冲区
    • 这是线程安全的
    • 编写在单独的线程中进行
    • 每次写入都会大量增加
    柜台高级设计

    柜台高级设计

    缓冲

    对于缓冲区,我使用了Google Guava 缓存

    缓冲结构

    创建缓冲区:

    private final LoadingCache<Counterable, BufferValue> cache;
    ...
    
    this.cache = CacheBuilder.newBuilder()
    	.maximumSize(bufferConfiguration.getMaximumSize())
    	.expireAfterWrite(bufferConfiguration.getExpireAfterWriteInSec(), TimeUnit.SECONDS)
    	.expireAfterAccess(bufferConfiguration.getExpireAfterAccessInSec(), TimeUnit.SECONDS)
    	.removalListener((notification) -> increaseCounter(notification))
    	.build(new BufferValueCacheLoader());
    ...

    可逆的描述如下)

    BufferValueCacheLoader实现了CacheLoader接口。 当我们调用增加(见下文)时,我们首先通过键从缓存中获取。 如果键不存在,则加载器返回值。

    BufferValueCacheLoader:

    public class BufferValueCacheLoader extends CacheLoader<Counterable, BufferValue> {
    	@Override
    	public BufferValue load(Counterable key) {
    		return new BufferValue();
    	}
    }

    BufferValue包装一个AtomicInteger (在某些时候我需要将其更改为Long)

    增加柜台

    增加计数器,如果超过阈值则发送:

    public void increase(Counterable key) {
    	BufferValue meter = cache.getUnchecked(key);
    	int currentValue = meter.increment();
    	if (currentValue > threashold) {
    		if (meter.compareAndSet(currentValue, currentValue - threashold)) {
    			increaseCounter(key, threashold);
    		}
    	}
    }

    当增加一个计数器时,我们首先从缓存中获取当前值(在加载程序的帮助下。如上所述)。 compareAndSet将自动检查是否具有相同的值(未被另一个线程修改)。 如果是这样,它将更新该值并返回true。 如果成功(返回true),则缓冲区调用更新程序。

    查看缓冲区

    开发服务之后,我想要一种查看缓冲区的方法。 因此,我实现了以下方法,该方法由前端层(Dropwizard的资源)使用。 Java 8 Stream和Lambda表达式的小示例。

    获取所有计数器在缓存中:

    return ImmutableMap.copyOf(cache.asMap())
    	.entrySet().stream()
    	.collect(
    		Collectors.toMap((entry) -> entry.getKey().toString(),
    		(entry) -> entry.getValue().getValue()));

    MongoDB

    我之所以选择MongoDB是因为两个原因:

    1. 我们的系统中有类似的实现,我们决定在那里也使用MongoDB。
    2. 易于与嵌入式服务器一起使用。

    我试图设计系统,以便可以选择其他任何持久性实现并进行更改。

    我使用吗啡作为MongoDB客户端层,而不是直接使用Java客户端。 使用Morphia,您可以创建dao ,它是与MongoDB集合的连接。 您还声明了一个简单的Java Bean(POJO),它表示集合中的文档。 一旦有了dao,就可以使用相当简单的API以“ Java方式”对集合进行操作。 您可以查询和其他任何CRUD操作,以及更多。

    我有两个操作:增加计数器和获取所有计数器。 服务实现不扩展Morphia的BasicDAO,而是具有一个继承它的类。 我使用了组合 (过度继承),因为我希望两种服务都具有更多的行为。

    为了与键表示保持一致,并从依赖代码中隐藏其实现方式,我使用了一个接口:可通过单个方法counterCount()来 抵消

    public interface Counterable {
    	String counterKey();
    }

    DAO,是服务内部的组成部分:

    final class MongoCountersDao extends BasicDAO<Counter, ObjectId> {
    	MongoCountersDao(Datastore ds) {
    		super(Counter.class, ds);
    	}
    }

    增加柜台

    MongoCountersUpdater扩展了实现CountersUpdater的AbstractCountersUpdater:

    @Override
    protected void increaseCounter(String key, int value) {
    	Query<Counter> query = dao.createQuery();
    	query.criteria("id").equal(key);
    	UpdateOperations<Counter> ops = dao.getDs().createUpdateOperations(Counter.class).inc("count", value);
    	dao.getDs().update(query, ops, true);
    }

    嵌入式MongoDB

    为了在持久层上运行测试,我想使用内存数据库。 有一个MongoDB插件。 使用此插件,您可以通过仅在运行时创建服务器来运行服务器,或者在Gradle中的maven / task中作为目标运行。

    Gradle上的嵌入式MongoDB

    稍后我将详细介绍Gradle,但这是设置嵌入式mongo所需的操作。

    dependencies {
    	// More dependencies here
    	testCompile 'com.sourcemuse.gradle.plugin:gradle-mongo-plugin:0.4.0'
    }

    设置属性

    mongo {
    	//	logFilePath: The desired log file path (defaults to 'embedded-mongo.log')
    	logging 'console'
    	mongoVersion 'PRODUCTION'
    	port 12345
    	//	storageLocation: The directory location from where embedded Mongo will run, such as /tmp/storage (defaults to a java temp directory)
    }

    嵌入式MongoDB Gradle任务

    • startMongoDb只会启动服务器。 它将运行直到停止它。
    • stopMongoDb将停止它。
    • startManagedMongoDb test ,这两个任务将在测试运行之前启动嵌入式服务器。 jvm完成(测试完成)后,服务器将关闭

    尽管我只触碰到冰山一角,但我开始看到Gradle的力量。 设置项目甚至都不是那么困难。

    Gradle设置

    首先,我在eclipse中创建了Gradle项目(安装插件后)。 我需要设置依赖项。 很简单。 就像行家一样。

    一个大的JAR输出

    当我想从Maven中的所有库中创建一个大jar时,我会使用shade插件。 我在寻找类似的东西,并发现gradle-one-jar插入。 https://github.com/rholder/gradle-one-jar我添加了该插件apply plugin: 'gradle-one-jar' 。 在类路径中添加了一个jar:

    buildscript {
    	repositories { mavenCentral() }
    	dependencies {
    		classpath 'com.sourcemuse.gradle.plugin:gradle-mongo-plugin:0.4.0'
    		classpath 'com.github.rholder:gradle-one-jar:1.0.4'
    	}
    }

    并添加了一个任务:

    mainClassName = 'org.eyalgo.server.dropwizard.CountersBufferApplication'
    task oneJar(type: OneJar) {
    	mainClass = mainClassName
    	archiveName = 'counters.jar'
    	mergeManifestFromJar = true
    }

    这些是我需要执行的必要操作,才能使应用程序运行。

    Dropwizard

    Dropwizard是一堆库,可以轻松快速地创建Web服务器。 它将Jetty用于HTTP,将Jersey用于REST。 它具有其他成熟的库来创建复杂的服务。 它可以用作易于开发的微服务。

    正如我在简介中所解释的,我不会介绍Dropwizard的所有功能和/或设置。 有很多的网站。 我将简要介绍为使应用程序运行而执行的操作。

    Gradle运行任务

    run { args 'server', './src/main/resources/config/counters.yml' }

    第一个参数是服务器。 第二个参数是配置文件的位置。 如果不将Dropwizard作为第一个参数,则会收到有关可能选项的错误消息。

    positional arguments:
      {server,check}         available commands

    我已经在Gradle部分中展示了如何创建一个jar。

    组态

    在Dropwizard中,您可以使用扩展Configuration的类来设置应用程序。 类中的字段应与yml配置文件中的属性对齐。

    优良作法是根据属性的用途/职责将其分组。 例如,我为mongo参数创建了一个组。

    为了使配置类正确读取子组,您需要创建一个与组中的属性对齐的类。

    然后,在主配置中,将该类添加为成员,并使用批注进行标记: @JsonProperty

    例:

    @JsonProperty("mongo")
    private MongoServicesFactory servicesFactory = new MongoServicesFactory();
    @JsonProperty("buffer")
    private BufferConfiguration bufferConfiguration = new BufferConfiguration();

    示例:更改端口

    这是配置文件的一部分,用于设置应用程序的端口。

    server:
      adminMinThreads: 1
      adminMaxThreads: 64
      applicationConnectors:
        - type: http
          port: 9090
      adminConnectors:
        - type: http
          port: 9091

    健康检查

    Dropwizard提供了开箱即用的基本管理API。 我将端口更改为9091。我为MongoDB连接创建了运行状况检查。 您需要扩展HealthCheck并实施检查方法。

    private final MongoClient mongo;
    ...
    protected Result check() throws Exception {
    	try {
    		mongo.getDatabaseNames();
    		return Result.healthy();
    	} catch (Exception e) {
    		return Result.unhealthy("Cannot connect to " + mongo.getAllAddress());
    	}
    }

    其他功能几乎是不言自明的,或者像任何入门教程一样简单。

    增强想法

    这些是我可能会尝试添加的内容。

    • 将测试添加到Dropwizard部分。
      该项目以PoC开头,因此与往常不同,我跳过了服务器部分中的测试。
      Dropwizard拥有“ 测试Dropwizard” ,我想尝试一下。
    • 不同的持久性实现。 (couchbase?Hazelcast?)。
    • 使用Google Guice进行注射。 并借助它注入不同的持久性实现。

    就这样。 希望有帮助。

    翻译自: https://www.javacodegeeks.com/2015/02/dropwizard-mongodb-and-gradle-experimenting.html

    mongodb实验报告

    展开全文
  • MongoDB

    2018-08-28 08:57:23
    初识MongoDB 1.介绍 2.作用 二.MongoDB的概念 1、数据库的概念 1.1、作用: 1.2、分类:(根据SQL语言的支持) 2、MongoDB基础概念 四、MongoDB的使用 1、连接MongoDB 1.1、DOS命令连接 1.2、点击安装...

    目录

    一.初识MongoDB

    1.介绍

    2.作用

    二.MongoDB的概念

    1、数据库的概念

    1.1、作用:

    1.2、分类:(根据SQL语言的支持)

    2、MongoDB基础概念

    四、MongoDB的使用

    1、连接MongoDB

    1.1、DOS命令连接

    1.2、点击安装目录下的mongo.exe-》E:\MongoDB\Server\4.0\bin\mongo.exe

    2、基础语法

    2.1、概念:

    2.2、语法

    3、功能与特性

    3.1、索引

    3.2、聚合(aggregate)

    3.3、复制(副本集)

    3.4、分片

    3.5、备份(mongodump)与恢复(mongorestore)

    3.6、监控

    4、java使用MongoDB


     

    参考:https://www.imooc.com/video/5934(慕课网)

    参考:http://www.runoob.com/mongodb/mongodb-intro.html(菜鸟教程)

    学习网站:

    • www.mongoing.com(国内官网) docs.mongoing.com(中文文档)
    • www.mongodb.org(官网)
    • www.mongodb.com
    • github.com/mongodb(源码)

     

    一.初识MongoDB

    1.介绍

    • 基于分布式文件存储的数据库。开源的NoSQL数据
    • 介于关系型数据库与非关系型数据库之间的产品(非关系型数据库中功能最全,最像关系型数据库的)。
    • 数据格式为类似Json的Bson格式。面向集合存储。
    • 支持的查询语言非常强大,语法类似于面向对象的查询语言,还支持对数据建立索引。
    • 特点:高性能、易部署、易使用、存储数据非常方便。(每个软件、框架都这样说......)

    2.作用

    • 为WEB应用提供高性能数据存储解决方案

     

    二.MongoDB的概念

    1、数据库的概念

    就是数据的仓库,不同的数据库存放数据的组织不同,且提供了不同种类的查询。

    1.1、作用:

    • 有组织的存放数据(只需根据数据库提供的接口写入)
    • 按照不同的需求进行查询。

    1.2、分类:(根据SQL语言的支持)

    SQL数据库:支持SQL语言的数据库。(由于表的定义,横向扩展不够灵活。即时存取、事物操作等有时也没必要使用)

    • Oracle
    • MySql

    NoSql数据库:不支持SQL语言的数据库。(没有多表连合查询)

    • Redis:键值存取,支持部分事物
    • MongoDB:本身不支持事物,没有表结构的概念

     

    2、MongoDB基础概念

    SQL术语/概念MongoDB术语/概念解释/说明
    databasedatabase数据库
    tablecollection数据库表/集合
    rowdocument数据记录行/文档
    columnfield数据字段/域
    indexindex索引
    table joins 表连接,MongoDB不支持
    primary keyprimary key主键,MongoDB自动将_id字段设置为主键

     

     

     

    MongoDB

    Mongo

    索引

    集合

    赋值集

    分片

    数据均衡

     

    三、部署数据库服务

    搭建简单的单击服务

    搭建具有冗余容错功能的复制集

    搭建大规模数据集群(拥有分片处理)

    完成集群的自动部署

     

     

    四、MongoDB的使用

    1、连接MongoDB

    语法(菜鸟教程):mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

    tips:不过好像这样输入不能连接,直接输入mongo就可以连接了

    ---------以下为后期补上内容--------

    查看mongodb是否启动:cmd中输入 net start MongoDB  。如果没有启动服务则会重新启动(net stop MongoDB 停止启动)

    mongo:是运行mongo的数据库。

    mongod:启动mongo的守护进程(mongo daemon),启动mongo的服务器。(不启动服务器也可运行,但是只能用于测试)

     

     

    1.1、DOS命令连接

    • 先建立环境变量“变量名:MONGODB_HOME,变量值:E:\MongoDB\Server\4.0”(如果不建立,则需通过cmd的cd命令到该目录下的bin去执行mongo.exe)
    • 在path命令中新建:“%MONGODB_HOME%\bin”
    • 然后可直接在cmd命令中输入“mongo”运行mongoDB服务(mongo好像也有的版本是mongodb)

    1.2、点击安装目录下的mongo.exe-》E:\MongoDB\Server\4.0\bin\mongo.exe

     

    2、基础语法

    2.1、概念:

    MongoDB默认数据库为test。

    文档的数据结构为BSON(和JSON基本一样,是JSON的二进制形式存储格式(Binary JSON))

    2.2、语法

    创建数据库:use DATABASE_NAME   (如果数据库不存在,则创建。否则切换到指定数据库。)

    查看所有数据库:show dbs  (刚创建的数据库如果没有插入数据,则无法通过show dbs显示)

    删除数据库:db.dropDatabase()

    删除集合:db.collection.drop()(collection为集合名字)

    创建集合:db.createCollection(name,options)  (当插入文档时会自动创建集合)

    • name:要创建的集合名字
    • options:可选,指定有关内存大小及索引的选项
    capped布尔

    (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。

    当该值为 true 时,必须指定 size 参数。

    autoIndexId布尔(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
    size数值

    (可选)为固定集合指定一个最大值(以字节计)。

    如果 capped 为 true,也需要指定该字段。

    max数值(可选)指定固定集合中包含文档的最大数量。

    插入文档同时创建集合:db.mycol2.insert({"key":"value",......})  (mycol2为集合名)

    查看已有集合:show collections

    插入文档:db.COLLECTION_NAME.insert(document)

    定义变量:document = ({key:'value',key2:'value2'})  (定义了变量就可以通过类似参数的形式进行文档插入(如上句语法))

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

    • 例:db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})  (更新查询到的数据的所有title)
    • 更新操作符(参考地址):https://blog.csdn.net/u014344668/article/details/52460682
    • query : update的查询条件,类似sql update查询内where后面的。
    • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
    • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
    • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
    • writeConcern :可选,抛出异常的级别。

    替换已有的文档:db.collection.save(<document>,{writeConcern:<document>})

    • document : 文档数据。
    • writeConcern :可选,抛出异常的级别。

    删除文档:db.conllection.remove(<query>,{justOne:<boolean>,writeConcern:<boolean>}) 

    • 好的习惯:remove前先执行find()来判断执行条件是否正确
    • 例:db.col.remove({'title':'MongoDB 教程'},true)  (只删除第一条标题title为“MongoDB 教程”的数据)
    • query :(可选)删除的文档的条件。
    • justOne : (可选)如果设为 true 或 1,则只删除一个文档。
    • writeConcern :(可选)抛出异常的级别。

     

    查询文档:db.col.find(query,projection)  (col为集合名,在加上“.pretty()”则可使查询出的内容工整)

    • query :可选,使用查询操作符指定查询条件
    • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
      //全为1(true)或为0(false),否则错误(除了inclusion模式id可指定为0)
      db.collection.find(query, {title: 1, by: 1}) // inclusion模式 指定返回的键,不返回其他键
      db.collection.find(query, {title: 0, by: 0}) // exclusion模式 指定不返回的键,返回其他键
    • 其他:findOne()方法,只返回一个文档
    • MongoDB与RDBMS WHERE语句比较:
      操作格式范例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
    • MongoDB AND条件:db.col.find({key1:value1, key2:value2}).pretty()
    • MongoDB OR条件($or):db.col.find({$or:[{key1: value1}, {key2:value2}]})  (注意与AND条件语法有点不同,因为需要让AND与OR可以联合使用)
    • AND和OR联合使用:db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
    • 还有一个条件操作符:$type

      基于BSON,检索匹配的数据类型(特殊)

      {<key>:{$type:<value>}}
      db.col.find({"title" : {$type : 2}})
      或:
      db.col.find({"title" : {$type : 'string'}})
      类型数字备注
      Double1 
      String2 
      Object3 
      Array4 
      Binary data5 
      Undefined6已废弃。
      Object id7 
      Boolean8 
      Date9 
      Null10 
      Regular Expression11 
      JavaScript13 
      Symbol14 
      JavaScript (with scope)15 
      32-bit integer16 
      Timestamp17 
      64-bit integer18 
      Min key255Query with -1.
      Max key127 

    读取指定数量记录:db.COLLECTION_NAME.find().limit(NUMBER)

    跳过指定数量记录:db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)  (先跳过,再读取指定数量)

    排序:db.COLLECTION_NAME.find().sort({KEY:1})(sort({key:value})。value:1为升序、-1用于降序)

     

    3、功能与特性

    3.1、索引

    • 能过极大的提高查询效率。(如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件,并选取那些符合查询条件的几率)
    • 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中。(存储了字段的值,而值又指向记录。空间换时间)
    • 索引是对数据库表中一列或多列的值进行排序的一种结构。

    创建索引:db.collection.createIndex(key,options)  

    • 例1:db.col.createIndex({"title":1}) (为字段title升序创建索引)
    • 例2:db.col.createIndex({'title':1,'description':-1})  (使用多个字段创建索引,关系型数据库也称作符合索引)
    • 例3:db.col.createIndex({open:1,close:1},{background:true})  (后台创建索引)
    • key:要创建索引的字段,1为升序建索引,-1为降序。
    • options
      ParameterTypeDescription
      backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
      uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
      namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
      dropDupsBoolean在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
      sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
      expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
      vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
      weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
      default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
      language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

     

    3.2、聚合(aggregate)

    主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。优点类似sql语句中的count(*)

    语法:db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

    例:db.mycol.aggregate([{$group : {_id:'$by_user',num_tutorial : {$sum : 1}}}])   

           类似于:select by_user,count(1) from mycol group by by_user

    聚合表达式:

    表达式描述实例
    $sum计算总和。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
    $avg计算平均值db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
    $min获取集合中所有文档对应值得最小值。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
    $max获取集合中所有文档对应值得最大值。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
    $push在结果文档中插入值到一个数组中。db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
    $addToSet在结果文档中插入值到一个数组中,但不创建副本。db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
    $first根据资源文档的排序获取第一个文档数据。db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
    $last根据资源文档的排序获取最后一个文档数据db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

    管道操作符:

    • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
    • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
    • $limit:用来限制MongoDB聚合管道返回的文档数。
    • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    • $group:将集合中的文档分组,可用于统计结果。
    • $sort:将输入文档排序后输出。
    • $geoNear:输出接近某一地理位置的有序文档。

     

    3.3、复制(副本集)

    • 是将数据同步在多个服务器的过程。(分布式读取数据)
    • 提供了数据的冗余备份,并在多个服务器上存储数据副本。(提高数据可用性、保证数据安全性)
    • 允许从硬件故障、服务中断中恢复数据

    3.3.1、原理

    至少需要2个节点,主节点(为单个,负责处理数据端请求)、从节点(可为多,负责复制主节点上的数据)。其中主节点不是固定的一个,任何节点都可以为主节点。(因为主节点宕机后,从节点会成为主节点)

    3.3.2 、特征

    • N 个节点的集群
    • 任何节点可作为主节点
    • 所有写入操作都在主节点上
    • 自动故障转移
    • 自动恢复

    3.3.3、使用

    • 如果MongoDB服务在运行,先停止:net stop mongodb
    • 通过 --replSet启动MongoDB:mongod --port 12345 --dbpath "E:\MongoDB\Server\4.0\data1" --replSet rs0
      • 名为rs0,端口号为123456
    • 新开一个cmd输入:mongo  (显示则会与之前的不同,为: rs0:PRIMARY>“在这儿输入命令”)
    • rs.initiate()启动一个新的副本集、rs.conf()查看副本集配置、rs.status()查看副本集状态
    • 添加副本集成员(需要多台服务器启动mongo服务):rs.add(HOST_NAME:PORT)
      • 例:rs.add("mongod1.net:27017")
      • 只能通过主节点将Mongo(PRIMARY)服务添加到副本集中。判断是否为主节点:db.isMaster()
      • 副本集与常见的主从不同,主从再主机宕机后所有服务将停止、副本集再主机宕机后副本会接管主节点。

     

    3.4、分片

    • 另一种集群,可以满足MongoDB数据量大量增长的需求。
    • 当数据量过大,一太机器不足以存储数据、不足以提供可接受的读写吞吐量。则可通过多台机器上分割数据,是的数据库系统能存储和处理更多的数据
    • 目前只做了解

    3.4.1、作用:

    • 复制所有的写入操作到主节点
    • 延迟的铭感数据会在主节点查询
    • 单个副本集限制在12个节点
    • 当请求量巨大时会出现内存不足(使用分别来分割数据)
    • 本地磁盘不足
    • 垂直扩展价格昂贵

    3.4.2、分片集群结构主要组件

    • shard:用于储存实际的数据块,实际生产环境中一个shard server角色可有几台机器组一个replica set承担,防止主机单点故障
    • Config Server:mongod实例,存储了整个ClusterMetadata,其中包括chunk信息
    • Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

     

    3.5、备份(mongodump)与恢复(mongorestore)

    备份:mongodump -h dbhost -d dbname -o dbdirectory

    • -h:MongoDB所在服务器地址。如:127.0.0.1或127.0.0.1:27017
    • -d:需要备份的数据库实例。如:test
    • -o:备份的数据存放位置。如:c:\data\dump (目录需提前建立)
    • 例:C:\Windows\system32>mongodump -h 127.0.0.1 -d test -o C:\data  (不需要(不能)再mongo下执行,打开cmd直接执行就好)
    • mongodump命令可选参数
      语法描述实例
      mongodump --host HOST_NAME --port PORT_NUMBER该命令将备份所有MongoDB数据mongodump --host runoob.com --port 27017
      mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY mongodump --dbpath /data/db/ --out /data/backup/
      mongodump --collection COLLECTION --db DB_NAME该命令将备份指定数据库的集合。mongodump --collection mycol --db test

    恢复:mongorestore -h <hostname><:port> -d dbname <path>

    • --host <:port>, -h <:port>:MongoDB所在服务器地址,默认为: localhost:27017
    • --db , -d :需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
    • --drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
    • <path>:mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录。
    • --dir:指定备份的目录,你不能同时指定 <path> 和 --dir 选项。
    • 例:mongorestore -h 127.0.0.1 -d test --drop C:\data\test

     

    3.6、监控

    在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能。这样在大流量得情况下可以很好的应对并保证MongoDB正常运作。

    MongoDB中提供了mongostat 和 mongotop 两个命令来监控MongoDB的运行情况。

     

    3.6.1、mongostat命令

    mongodb自带的状态监测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。

    如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。

    使用:启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat命令

    • 例:E:\MongoDB\Server\4.0\bin>mongostat  (如果配置了环境变量则无需进入该目录,直接输入mongostat即可)

    3.6.2、mongotop命令

    也是一个内置工具,提供了一个方法,用来跟踪一个MongoDB实例,查看哪些大量的时间花费在读取和写入数据。

     mongotop提供每个集合的水平的统计数据。默认情况下,mongotop返回值的每一秒。

    使用:输入mongotop命令

    • 例:C:\Users\Administrator>mongotop  (配置了环境变量,可直接输入mongotop)
    • 例2:E:\mongodb-win32-x86_64-2.2.1\bin>mongotop 10
      • 后面的10是<sleeptime>参数 ,可以不使用,等待的时间长度,以秒为单位,mongotop等待调用之间。通过的默认mongotop返回数据的每一秒。
    • 例3:E:\mongodb-win32-x86_64-2.2.1\bin>mongotop --locks
      • 报告每个数据库锁的使用情况(下面为输出结果字段说明)
      • ns:包含数据库命名空间,后者结合了数据库名称和集合。
      • db:包含数据库的名称。名为 . 的数据库针对全局锁定,而非特定数据库。
      • total:mongod花费的时间工作在这个命名空间提供总额。
      • read:提供了大量的时间,这mongod花费在执行读操作,在此命名空间。
      • write:提供这个命名空间进行写操作,这mongod花了大量的时间。

     

    4、java使用MongoDB

    MongoDB3.0以上在连接时需要三个jar包:参考:https://blog.csdn.net/hotdust/article/details/51315197

    <dependency>
    	<groupId>org.mongodb</groupId>
    	<artifactId>mongo-java-driver</artifactId>
    	<version>3.0.4</version>
    </dependency>
    <dependency>
    	<groupId>org.mongodb</groupId>
    	<artifactId>mongodb-driver</artifactId>
    	<version>3.0.4</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-core -->
    <dependency>
    	<groupId>org.mongodb</groupId>
    	<artifactId>mongodb-driver-core</artifactId>
    	<version>3.0.4</version>
    </dependency>

    MongDB在IDEA上使用实例:(使用了JUnit测试工具)

    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoCredential;
    import com.mongodb.ServerAddress;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoCursor;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import org.bson.Document;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class MongoDBJDBC {
        //连接到数据库
        MongoDatabase mgDatabase;
    
        //测试时会自动在测试前运行的方法:获取MongoDB的连接
        @Before
        public void getmgDatabase(){
            try{
                //连接到mongodb服务
                MongoClient mgClient = new MongoClient("localhost",27017);
                //连接到数据库
                mgDatabase = mgClient.getDatabase("test");
                System.out.println("连接成功");
    
            }catch(Exception e){
                System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            }
        }
    
        //当连接数据库需要用户名、密码时使用
    //    @Before
    //    public void getmgDatabase(){
    //        try {
    //            //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
    //            //ServerAddress()两个参数分别为 服务器地址 和 端口
    //            ServerAddress serverAddress = new ServerAddress("localhost",27017);
    //            List<ServerAddress> addrs = new ArrayList<ServerAddress>();
    //            addrs.add(serverAddress);
    //
    //            //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
    //            MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
    //            List<MongoCredential> credentials = new ArrayList<MongoCredential>();
    //            credentials.add(credential);
    //
    //            //通过连接认证获取MongoDB连接
    //            MongoClient mongoClient = new MongoClient(addrs,credentials);
    //
    //            //连接到数据库
    //            mgDatabase = mongoClient.getDatabase("databaseName");
    //            System.out.println("数据库连接成功");
    //        } catch (Exception e) {
    //            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
    //        }
    //    }
    
        //1.创建集合
        @Test
        public void createConllection(){
            mgDatabase.createCollection("test2");
            System.out.println("集合创建成功");
        }
    
        //2.获取集合
        @Test
        public void getCollection(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
        }
    
        //3.插入文档
        @Test
        public void insertDocument(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
            //插入文档
            /**
             * 1. 创建文档 org.bson.Document 参数为key-value的格式
             * 2. 创建文档集合List<Document>
             * 3. 将文档集合插入数据库集合中 collection.insertMany(List<Document>) 插入单个文档可以用 collection.insertOne(Document)
             * */
            Document document = new Document("title","MongoDB").
                    append("description", "database").
                    append("likes", 101).
                    append("by", "又是一条记录");
            List<Document> documents = new ArrayList<Document>();
            documents.add(document);
    
            collection.insertMany(documents);
            System.out.println("文档插入成功");
        }
    
        //4.检查所有文档
        @Test
        public void findDocument(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
    
            //检索所有文档
            /**
             * 1. 获取迭代器FindIterable<Document>
             * 2. 获取游标MongoCursor<Document>
             * 3. 通过游标遍历检索出的文档集合
             * */
            FindIterable<Document> findIterable = collection.find();
            MongoCursor<Document> mgCursor = findIterable.iterator();
            while(mgCursor.hasNext()){
                System.out.println(mgCursor.next());
            }
    
            System.out.println("检查完成");
        }
    
        //5.更新文档
        @Test
        public void updateDocument(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
    
            //更新文档  将文档中likes=100的文档修改为likes=200
            collection.updateMany(Filters.eq("likes",101),new Document("$set",new Document("likes",210)));
    
            System.out.println("集合更新成功");
        }
    
        //6.1、删除第一个文档
        @Test
        public void deleteOneDocument(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
    
            //删除符合条件的第一个文档
            collection.deleteOne(Filters.eq("likes",200));
    
            System.out.println("删除符合条件的第一个文档成功");
        }
    
        //6.1、删除符合条件的所有文档
        @Test
        public void deleteManyDocument(){
            MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
            System.out.println("集合test选择成功");
    
            //删除符合条件的所有文档(就是变了一个deleteMany方法)
            collection.deleteMany(Filters.eq("likes",210));
    
            System.out.println("删除符合条件的所有文档成功");
        }
    
    }
    

     

    五、MongoDB高级教程

    1、MongoDB关系

    表示多个文档在逻辑上的相互联系。

    文档间可以通过嵌入引用来建立联系。

    关系:

    • 1:1(1对1)
    • 1:N(一对多)
    • N:1(多对1)
    • N:N(多对多)

    例:一个用户可以有多个地址(这个只是一个说明,不做实际应用)

    //user文档简单结构
    {
       "_id":ObjectId("52ffc33cd85242f436000001"),
       "name": "Tom Hanks",
       "contact": "987654321",
       "dob": "01-01-1991"
    }
    
    
    //address文档简单结构
    {
       "_id":ObjectId("52ffc4a5d85242602e000000"),
       "building": "22 A, Indiana Apt",
       "pincode": 123456,
       "city": "Los Angeles",
       "state": "California"
    } 

    1.1、嵌入式关系

    • 使用嵌入式关系,我们可以把用户地址嵌入到用户的文档中。
    • 不足:如果用户和用户地址在不断增加,数据量不断变大,会影响读写性能
    //不用想复杂了,就是将地址以数组的形式保存在address中
       "_id":ObjectId("52ffc33cd85242f436000001"),
       "contact": "987654321",
       "dob": "01-01-1991",
       "name": "Tom Benzamin",
       "address": [
          {
             "building": "22 A, Indiana Apt",
             "pincode": 123456,
             "city": "Los Angeles",
             "state": "California"
          },
          {
             "building": "170 A, Acropolis Apt",
             "pincode": 456789,
             "city": "Chicago",
             "state": "Illinois"
          }]
    } 
    
    
    
    //可以使用这种方式来查询地址
    >db.users.findOne({"name":"Tom Benzamin"},{"address"}:1)
    //只显示满足条件的地址
    db.test.find({"address":{$elemMatch:{"pincode":123456}}},{address:{$elemMatch:{"pincode":123456}}}).pretty()

     

    1.2、引用式关系

    引用式关系是设计数据库时经常用到的方法,这种方法把用户数据文档和用户地址数据文档分开,通过引用文档的id字段来建立关系。

    //1、插入用户记录
    > db.user.insert({
    ...    "_id":ObjectId("52ffc33cd85242f436000001"),
    ...    "contact": "987654321",
    ...    "dob": "01-01-1991",
    ...    "name": "Tom Benzamin",
    ...    "address_ids": [
    ...       ObjectId("52ffc4a5d85242602e000000"),
    ...       ObjectId("52ffc4a5d85242602e000001")
    ...    ]
    ... })
    
    //2、插入城市记录
    > db.address.insert({address:"长沙"})
    WriteResult({ "nInserted" : 1 })
    > db.address.insert({address:"北京"})
    WriteResult({ "nInserted" : 1 })
    > db.address.insert({address:"上海"})
    WriteResult({ "nInserted" : 1 })
    > db.address.insert({address:"广州"})
    WriteResult({ "nInserted" : 1 })
    > db.address.insert({address:"郴州"})
    WriteResult({ "nInserted" : 1 })
    
    //3、中间省略查询城市记录步骤(获取_id)
    
    //4、修改用户的地址(address_ids)为查询出的地址"_id"
    > db.user.update({contact:"987654321"},{$set:{address_ids:[ObjectId("5b7693f2ddc293f504101a07"), ObjectId("5b7693f8ddc293f504101a08")]}})
    
    //5、获取用户的地址id
    > var result = db.user.findOne({"name":"Tom Benzamin"},{"address_ids":1})
    
    //6、获取相关联的地址(可直接输入变量名输出)
    >var address = db.address.find({_id:{"$in":result["address_ids"]}})

     

    2.数据库引用

    • 在4.1中的引用式关系中,引用又分为两种:手动引用(Manual References)、DBRefs
    • 理解:我们在不同的集合中 (address_home, address_office, address_mailing, 等)存储不同的地址(住址,办公室地址,邮件地址等)。这样,我们在调用不同地址时,也需要指定集合,一个文档从多个集合引用文档,我们应该使用 DBRefs。

    DBRef的形式:{ $ref : , $id : , $db : }

    • $ref:集合名称
    • $id:引用的id
    • $db:数据库名称,可选参数
    • 实例:
      //address DBRef 字段指定了引用的地址文档是在 runoob 数据库下的 address_home 集合,id 为 534009e4d852427820000002。
      {
         "_id":ObjectId("53402597d852426020000002"),
         "address": {
         "$ref": "address_home",
         "$id": ObjectId("534009e4d852427820000002"),
         "$db": "runoob"},
         "contact": "987654321",
         "dob": "01-01-1991",
         "name": "Tom Benzamin"
      }
      
      
      //我们通过指定 $ref 参数(address_home 集合)来查找集合中指定id的用户地址信息:
      >var user = db.users.findOne({"name":"Tom Benzamin"})
      >var dbRef = user.address
      >db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
      
      //结果
      {
         "_id" : ObjectId("534009e4d852427820000002"),
         "building" : "22 A, Indiana Apt",
         "pincode" : 123456,
         "city" : "Los Angeles",
         "state" : "California"
      }

       

    3、覆盖索引查询

    达成覆盖索引查询的条件:

    • 所有的查询字段是索引的一部分(“一部分” 的理解就是:有可能这个字段是数组或文档,但是又与“不能达成”有冲突了)
    • 所有的查询返回字段在同一个索引中

    原理:

    • 由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配 查询条件和返回 使用相同索引的查询结果。
    • 因为索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多。

    例:

    //user集合
    {
       "_id": ObjectId("53402597d852426020000002"),
       "contact": "987654321",
       "dob": "01-01-1991",
       "gender": "M",
       "name": "Tom Benzamin",
       "user_name": "tombenzamin"
    }
    
    //创建联合索引,字段为 gender 和 user_name :
    >db.users.ensureIndex({gender:1,user_name:1})
    
    
    //执行查询,该索引会覆盖这次查询(MongoDB的不会去数据库文件中查找。相反,它会从索引中提取数据,这是非常快速的数据查询。)
    //由于我们的索引中不包括 _id 字段,_id在查询中会默认返回,我们可以在MongoDB的查询结果集中排除它。
    >db.users.find({gender:"M"},{user_name:1,_id:0})    
    
    //执行查询(这种不会覆盖,因为他没有排除id)
    >db.users.find({gender:"M"},{user_name:1})

    以下的查询,不能使用覆盖索引查询:

    • 所有索引字段是一个数组
    • 所有索引字段是一个子文档

     

     

    2.2

    1、文档的读写更新删除

    2、各种不同类型的索引的创建与使用

    3、复杂的聚合查询

    4、对数据集合进行分片,在不同分片中维持数据均衡

    5、数据备份与恢复

    6、数据迁移

     

    五、运维

    1、部署MongoDb集群

    2、处理多种常见故障(保证集群的正常运行)

    单节点失效如何恢复工作

    数据库意外被杀死,如何进行数据恢复

    数据库发生拒绝服务时如何排查原因

    数据库磁盘快满时如何处理

     

     

     

     

    展开全文
  • mongoDb

    2015-10-22 09:56:24
    其中重要的解决方案之一就是MongoDBMongoDB是面向文档的弱结构化存储方案,使用JSON格式来展现、查询和修改数据。 MongoDB文档相当完备,扩展规模与安装一样简单。它提供冗余、切片、索引以及map/reduce等概念支持...
    什么是mogodb?
    
    MongoDB介绍
    当今NoSQL领域中有很多有力的竞争者通过多种方式来处理海量数据问题。其中重要的解决方案之一就是MongoDB。 MongoDB是面向文档的弱结构化存储方案使用JSON格式来展现、查询和修改数据。
    MongoDB文档相当完备,扩展规模与安装一样简单。它提供冗余、切片、索引以及map/reduce等概念支持。MongoDB的开源社区非常大且非常活跃。MongoDB在很多大型产品中被实际运用,如:Disney, Craigslist, Foursquare, Github 和SourceForge。MongoDB是一个开源项目,由10gen.com建立并维护,该公司由DoubleClick的前任执行人员创立。同时,10gen也提供了极好的商业支持与参与建设。
    MongoDB 与 NoSQL: 缺陷与优势
    MongoDB作为一个可用NoSQL方案具有很多优势。我刚开始接触nosql数据库了解了一系列基于Java的方案,并且花了大量的时间来弄懂什么是列家族,Hadoop与HBase的关系,ZooKeeper到底是什么。当我终于全部清楚之后,发现Cassandra与HBase确实是对于NoSQL领域非常可靠、可信赖的解决方案。但与其他的解决方案相比,MongoDB让我在能够开始写代码之前,不用理解那么多的概念。
    与其他软件相似,MongoDB也存在缺陷。经过一段时间使用MongoDB,我列举经历过并需要注意的一些事情,我成为“Gotchas”:
    不要按照关系型数据库来思考。这很明显,MongoDB使得构建和执行复杂查询变得非常容易。当实际使用的时候,你会主要关注于效率问题(像我一样)。
    MongoDB的索引是二进制的树。如果你不是很熟悉B-tree,可能需要了解一下。这些都涉及到构建符合提供查询条件需求的建立索引的方式。
    ● 小心的设计索引结构。这涉及到上面提到的B-tree。刚开始我的索引包含文档中的很多字段,以防我会使用到他们。不要犯同样的错误。我有一个很小集合的索引(大约1千万记录)增长到超过17GB的空间,比集合本身还大。你应该不会想要索引一个包含成百上千个实体的列表字段。
    ● MongoDB采用了非常有意思的方式来实现NoSQL:采用BSON作为存储,JSON作为展示,JavaScript用于管理和Map/Reduce。因此也引起了一些小问题比如这个 (破坏了Number和Long的相等操作),在MongoDB逐渐流行之后,可能会不断的展示出来。
    MongoDB, 命令行与驱动
    MongoDB基本是使用JavaScript客户端命令行程序来进行复杂任务管理的,如数据整合和简单信息处理,编程都是完全使用JavaScript语言来的。本文中,我们会展示命令行的使用示例。现在有大量的MongoDB客户端产品提供,并且由MongoDB社区来支持驱动。通常每种编程语言都有驱动,并且所有流行的语言都有包括,一些不那么流行的也包含在内。这篇文章展示了使用MongoDB的Java驱动,并使用一个ORM库(MJORM)与之进行比较。
    介绍 MJORM: MongoDB的ORM方案
    在解决的众多有意思的问题中,最近NoSQL数据存储在开发者中主要的问题趋势就是对象关系映射。对象关系映射就是将传统中保存在关系型数据库中的持久化数据映射为在应用程序中使用的对象。这使得编程语言使用起来更加流畅和自然。
    MongoDB面向文档的架构使得它非常适合对象关系映射,因为文档本身就是以对象形式存储的。可惜没有太多的MongoDB的Java对象关系映射库,但是还是有一些,如morphia-(A type-safe Java library for MongoDB), spring-data(SpringData项目的MongoDB实现)
    这些ORM库大量使用了注解,因为一些原因对我不适合,其中最重要的就是这些被注解的对象在多个项目中的兼容性问题。这让我开始了mongo-Java-orm 或者 “MJORM” (发音 me-yorm)项目,一个MongoDB的Java对象关系映射项目。MJORM是在MIT许可之下,并且在发布在了google code project。项目采用maven构建,并且maven构件仓库托管于google code版本控制服务器。MJORM的最新可用发布版本为0.15,已经由一些项目使用与生产环境中。
    开始使用ORM
    加入MJORM 库
    Maven的使用者首先应当在pom.xml中加入MJORM的maven仓库,使得MJORM构件可用。
    1. <repository>
    2. <id>mjorm-webdav-maven-repo</id>
    3. <name>mjorm maven repository</name>
    4. <url>http://mongo-Java-orm.googlecode.com/svn/maven/repo/</url>
    5. <layout>default</layout>
    6. </repository>
    然后加入依赖:
    1. <dependency>
    2. <groupId>com.googlecode</groupId>
    3. <artifactId>mongo-Java-orm</artifactId>
    4. <version>0.15</version>
    5. </dependency>
    这样就可以在应用中引入MJORM代码。假如没有使用maven,则你需要手动下载MJORM的pom.xml中列举的所有依赖。 建立 POJOs依赖已经导入,可以开始编码了。我们从POJO开始:
    1. class Author {
    2. private String firstName;
    3. private String lastName;
    4. // ... setters and getters ...
    5. }
    6.
    7. class Book {
    8. private String id;
    9. private String isbn;
    10. private String title;
    11. private String description;
    12. private Author author;
    13. // ... setters and getters ...
    14. }
    我们在这个对象模型中的描述是,作者有ID、姓和名,书有ID、ISNB、标题、描述和作者。 你可能注意到书的id属性是一个字符串,这是为了适应MongoDB的对象ID类型。MongoDB的ID是一个12字节的二进制值显示为一个十六进制的字符串。MongoDB要求集合中的每个文档都必须有一个唯一id,但不要求一定要是ObjectId。目前MJORM只支持ObjectId,并且显示为字符串。 你也可能注意到了Author没有id字段。这是因为Book是它的父文档,因此不需要有id。记住,MongoDB只要求集合中的文档在根级别的id。 创建XML映射文件 下一个步骤就是建立XML映射文件,MJORM能够将MongoDB文档转换为对象。我们为每个文档创建一个对象作为示范,无论将所有的映射放在一个XML文件中还是分开都是可以的。
    Author.mjorm.xml:
    1. <?xml version="1.0"?>
    2. <descriptors>
    3. <object>
    4. <property name="firstName" />
    5. <property name="lastName" />
    6. </object>
    7. </descriptors>
    Book.mjorm.xml:
    1. <?xml version="1.0"?>
    2. <descriptors>
    3. <object>
    4. <property name="id" id="true" auto="true" />
    5. <property name="isbn" />
    6. <property name="title" />
    7. <property name="description" />
    8. <property name="author" />
    9. </object>
    10. </descriptors>
    这些映射文件能够很好的自解释。descriptors 元素是根元素,必须包含在每个映射文件中。在它下面是object元素定义了文档与之对应的类。Object包含的property 元素主要用于描述POJO中的属性以及这些属性如何与MongoDB中的文档想对应。property 元素至少必须包含一个name 属性,这个元素就是POJO和MongoDB的文档中的属性名称。column 属性则是可选的,用于特定一个在MongoDB文档中的可选属性名称。 property 元素当中的id属性应该是对象的唯一识别。一个对象只能有一个property 元素包含id属性。auto 的设置会使得MJORM在持久化时为该属性自动生成一个值。 可以在google code的MJORM项目主页中查看XML映射文件的更多细节描述。 整合POJO与XML我们创建了数据模型以及映射文件,使得MJORM可以从MongoDB序列号以及反序列号POJO。我们可以进行一些有意思的事情了,首先打开MongoDB的链接:
    1. Mongo mongo = new Mongo(
    2. new MongoURI("mongodb://localhost/mjormIsFun")); // 10gen driver
    Mongo 对象是由10gen编写的Java驱动提供的。示例中连接了一个本地的MongoDB实例中的mjormIsFun数据库。接下来我们创建MJORM ObjectMapper 。目前ObjectMapper 在MJORM中的唯一实现就是XmlDescriptorObjectMapper,使用XML结构描述信息。可能之后会增加对注解或其他结构定义的支持。
    1. XmlDescriptorObjectMapper objectMapper = new XmlDescriptorObjectMapper();
    2. mapper.addXmlObjectDescriptor(new File("Book.mjorm.xml"));
    3. mapper.addXmlObjectDescriptor(new File("Author.mjorm.xml"));
    建立好了XmlDescriptorObjectMapper 并且加入了映射文件。接下来建立由MJORM提供的MongoDao 对象的实例。
    1. DB db = mongo.getDB("mjormIsFun"); // 10gen driver
    2. MongoDao dao = new MongoDaoImpl(db, objectMapper);
    首先我们要获得10gen驱动提供的DB对象实例。然后使用DB和ObjectMapper 建立MongoDao 。我们准备开始持久化数据,建立一个Book 然后保存到MongoDB中。
    1. Book book = new Book();
    2. book.setIsbn("1594743061");
    3. book.setTitle("MongoDB is fun");
    4. book.setDescription("...");
    5. book = dao.createObject("books", book);
    6. System.out.println(book.getId()); // 4f96309f762dd76ece5a9595
    首先建立Book 对象并且填值,然后调用MongoDao 的 createObject 方法,将Book 对象传入”books” 的集合中。MJORM会按照之前的xml映射文件将Book 转换为DBObject (这是10gen的Java驱动使用的基本类型),并保存一个新的文档进”books” 集合。MJORM返回Book对象时,id属性会被填充。请注意,MongoDB默认是不需要在使用前建立数据库或集合的,系统会在需要时自动创建,这可能会造成某些困扰。在MongoDB的命令行中查看Book对象大概如下:
    1. > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
    2. {
    3. "_id": ObjectId("4f96309f762dd76ece5a9595"),
    4. "isbn": "1594743061",
    5. "title": "MongoDB is fun",
    6. "description": "..."
    7. }
    我们来看看假如不用MJORM而直接使用10gen的Java驱动,如何使用createObject 方法:
    1. Book book = new Book();
    2. book.setIsbn("1594743061");
    3. book.setTitle("MongoDB is fun");
    4. book.setDescription("...");
    5. DBObject bookObj = BasicDBObjectBuilder.start()
    6. .add("isbn", book.getIsbn())
    7. .add("title", book.getTitle())
    8. .add("description", book.getDescription())
    9. .get();
    10. // 'db' is our DB object from earlier
    11. DBCollection col = db.getCollection("books");
    12. col.insert(bookObj);
    13. ObjectId id = ObjectId.class.cast(bookObj.get("_id"));
    14. System.out.println(id.toStringMongod()); // 4f96309f762dd76ece5a9595
    下面进行对象的查询:
    1. Book book = dao.readObject("books", "4f96309f762dd76ece5a9595", Book.class);
    2. System.out.println(book.getTitle()); // "MongoDB is fun"
    readObject 方法根据给定文档的id从指定的集合中读取文档,转换为对象(再次使用映射文件)并返回。 敏锐的读者会注意到Book还没有指定Author,仍然保存了。这归咎于MongoDB的结构不敏感的特性。我们不能要求集合中的文档包含所有属性(id属性是必须的),所有在MongoDB中没有Author的Book是可以的。我们现在为Book添加一个Author并且更新一下:
    1. Author author = new Author();
    2. author.setFirstName("Brian");
    3. author.setLastName("Dilley");
    4. book.setAuthor(author);
    5. dao.updateObject("books", "4f96309f762dd76ece5a9595", book);
    现在Book就包含了Author,并且在MongoDB中持久化了。现在在命令行查看了Book:
    1. > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
    2. {
    3. "_id": ObjectId("4f96309f762dd76ece5a9595"),
    4. "isbn": "1594743061",
    5. "title": "MongoDB is fun",
    6. "description": "..."
    7. "author": {
    8. "firstName": "Brian",
    9. "lastName": "Dilley"
    10. }
    11. }
    可以看到持久化的Book中已经包含了author。不使用MJORM来操作一遍:
    1. Author author = new Author();
    2. author.setFirstName("Brian");
    3. author.setLastName("Dilley");
    4. book.setAuthor(author);
    5. DBObject bookObj = BasicDBObjectBuilder.start()
    6. .add("isbn", book.getIsbn())
    7. .add("title", book.getTitle())
    8. .add("description", book.getDescription())
    9. .push("author")
    10. .add("firstName", author.getFirstName())
    11. .add("lastName", author.getLastName())
    12. .pop()
    13. .get();
    14. DBCollection col = db.getCollection("books");
    15. col.update(new BasicDBObject("_id", bookObj.get("_id")), bookObj);
    对于MongoDao 方法的深入讨论已经超出了本文的范围。对于将MJORM有兴趣用于实际项目中的用户强烈建议了解一下MJORM项目提供的相关文档,或者MongoDao 接口提供的相关用法。
    总结
    希望这篇文章对MongoDB和MJORM的亮点有所展示。MongDB是一个优秀的呃NoSQL数据存储,有着大量优秀的特性,会是NoSQL市场中长期竞争者。若你会在一个Java项目中使用MongoDB,希望你也能够考虑使用MJORM作为你的ORM框架。十分欢迎大家提交特性需求、错误异常报告、文档和源码修正。
    作者 Bio
    Brian Dilley 是一个经验丰富的高级工程师以及项目领导,在Java/Java EE /Spring Framework/Linux内部结构理解和管理有着超过13年的经验。Brian对于创业公司有很多经验,推向市场,构建/维护产品等。他是Iaas、cloud、PHP和Linux的专家,熟悉产品的采购、安装及配置定义,以及公司的软硬件架构包括负载均衡、数据库、微博等。可以follow Brian的 Twitter 。
    英文原文:Brian Dilley 本文由陈晨(@一酌散千忧)编译并投稿于伯乐在线。如果您也愿意 分享一份自己的原创/译文,可以 从这里开始~
    展开全文
  • Mongodb

    2017-08-16 10:37:00
    文章来源:http://www.runoob.com/mongodb/mongodb-tutorial.html NoSQL简介 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。 在现代的计算系统上每天网络上都会产生庞大的数据量。 这些数据有很大一部分...

    文章来源:http://www.runoob.com/mongodb/mongodb-tutorial.html

    NoSQL 简介

    NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。

    在现代的计算系统上每天网络上都会产生庞大的数据量。

    这些数据有很大一部分是由关系数据库管理系统(RDMBSs)来处理。 1970年 E.F.Codd's提出的关系模型的论文 "A relational model of data for large shared data banks",这使得数据建模和应用程序编程更加简单。

    通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。

    NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

    关系型数据库遵循ACID规则

    事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:

     

    1、A (Atomicity) 原子性

    原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。

     

    比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。

     

    2、C (Consistency) 一致性

    一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

     

    例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。

    3、I (Isolation) 独立性

    所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。

    比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。

    4、D (Durability) 持久性

    持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

     

    分布式系统

    分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。

    分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。

    因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。

    分布式系统可以应用在在不同的平台上如:Pc、工作站、局域网和广域网上等。

     

    分布式计算的优点

    可靠性(容错) :

    分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。

    可扩展性:

    在分布式计算系统可以根据需要增加更多的机器。

    资源共享:

    共享数据是必不可少的应用,如银行,预订系统。

    灵活性:

    由于该系统是非常灵活的,它很容易安装,实施和调试新的服务。

    更快的速度:

    分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度。

    开放系统:

    由于它是开放的系统,本地或者远程都可以访问到该服务。

    更高的性能:

    相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)。

     

    分布式计算的缺点

    故障排除:

    故障排除和诊断问题。

    软件:

    更少的软件支持是分布式计算系统的主要缺点。

    网络:

    网络基础设施的问题,包括:传输问题,高负载,信息丢失等。

    安全性:

    开发系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。

     

    什么是NoSQL?

    NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

    NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

    为什么使用NoSQL ?

    今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的数据。

    web-data-image

    实例

    社会化关系网:

    Each record: UserID1, UserID2 
    Separate records: UserID, first_name,last_name, age, gender,... 
    Task: Find all friends of friends of friends of ... friends of a given user.

    Wikipedia 页面 :

    Large collection of documents 
    Combination of structured and unstructured data 
    Task: Retrieve all pages regarding athletics of Summer Olympic before 1950.

     

    RDBMS vs NoSQL

    RDBMS 
    - 高度组织化结构化数据 
    - 结构化查询语言(SQL) (SQL) 
    - 数据和关系都存储在单独的表中。 
    - 数据操纵语言,数据定义语言 
    - 严格的一致性
    - 基础事务

    NoSQL 
    - 代表着不仅仅是SQL
    - 没有声明性查询语言
    - 没有预定义的模式
    -键 - 值对存储,列存储,文档存储,图形数据库
    - 最终一致性,而非ACID属性
    - 非结构化和不可预知的数据
    - CAP定理 
    - 高性能,高可用性和可伸缩性

    bigdata 

    NoSQL 简史

    NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。

    2009年,Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论[2],来自Rackspace的Eric Evans再次提出了NoSQL的概念,这时的NoSQL主要指非关系型、分布式、不提供ACID的数据库设计模式。

    2009年在亚特兰大举行的"no:sql(east)"讨论会是一个里程碑,其口号是"select fun, profit from real_world where relational=false;"。因此,对NoSQL最普遍的解释是"非关联型的",强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。

     

    CAP定理(CAP theorem)

    在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

    • 一致性(Consistency) (所有节点在同一时间具有相同的数据)
    • 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
    • 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

    CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。

    因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:

    • CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
    • CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
    • AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

    cap-theoram-image 

    NoSQL的优点/缺点

    优点:

    • - 高可扩展性
    • - 分布式计算
    • - 低成本
    • - 架构的灵活性,半结构化数据
    • - 没有复杂的关系

    缺点:

    • - 没有标准化
    • - 有限的查询功能(到目前为止)
    • - 最终一致是不直观的程序

     

    BASE

    BASE:Basically Available, Soft-state, Eventually Consistent。 由 Eric Brewer 定义。

    CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。

    BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:

    • Basically Availble --基本可用
    • Soft-state --软状态/柔性事务。 "Soft state" 可以理解为"无连接"的, 而 "Hard state" 是"面向连接"的
    • Eventual Consistency --最终一致性 最终一致性, 也是是 ACID 的最终目的。

     

    ACID vs BASE

    ACIDBASE
    原子性(Atomicity)基本可用(Basically Available)
    一致性(Consistency)软状态/柔性事务(Soft state)
    隔离性(Isolation)最终一致性 (Eventual consistency)
    持久性 (Durable) 

     

    NoSQL 数据库分类

     

    类型部分代表

     

    特点
    列存储

    Hbase

    Cassandra

    Hypertable

    顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。

    文档存储

    MongoDB

    CouchDB

    文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。

    key-value存储

    Tokyo Cabinet / Tyrant

    Berkeley DB

    MemcacheDB

    Redis

    可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)

    图存储

    Neo4J

    FlockDB

    图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。

    对象存储

    db4o

    Versant

    通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。

    xml数据库

    Berkeley DB XML

    BaseX

    高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。

     

    什么是MongoDB ?

    MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

    在高负载的情况下,添加更多的节点,可以保证服务器性能。

    MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

    MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。


    主要特点

    • MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。
    • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
    • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
    • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
    • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
    • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
    • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
    • Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
    • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
    • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
    • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
    • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
    • MongoDB安装简单。

    历史

    • 2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。
    • 2012年05月23日,MongoDB2.1 开发分支发布了! 该版本采用全新架构,包含诸多增强。
    • 2012年06月06日,MongoDB 2.0.6 发布,分布式文档数据库。
    • 2013年04月23日,MongoDB 2.4.3 发布,此版本包括了一些性能优化,功能增强以及bug修复。
    • 2013年08月20日,MongoDB 2.4.6 发布。
    • 2013年11月01日,MongoDB 2.4.8 发布。
    • ……

    MongoDB 下载

    你可以在mongodb官网下载该安装包,地址为:https://www.mongodb.com/download-center#community。MonggoDB支持以下平台:

    • OS X 32-bit
    • OS X 64-bit
    • Linux 32-bit
    • Linux 64-bit
    • Windows 32-bit
    • Windows 64-bit
    • Solaris i86pc
    • Solaris 64

    语言支持

    MongoDB有官方的驱动如下:


    MongoDB 工具

    有几种可用于MongoDB的管理工具。

    监控

    MongoDB提供了网络和系统监控工具Munin,它作为一个插件应用于MongoDB中。

    Gangila是MongoDB高性能的系统监视的工具,它作为一个插件应用于MongoDB中。

    基于图形界面的开源工具 Cacti, 用于查看CPU负载, 网络带宽利用率,它也提供了一个应用于监控 MongoDB 的插件。

    GUI

    • Fang of Mongo – 网页式,由Django和jQuery所构成。
    • Futon4Mongo – 一个CouchDB Futon web的mongodb山寨版。
    • Mongo3 – Ruby写成。
    • MongoHub – 适用于OSX的应用程序。
    • Opricot – 一个基于浏览器的MongoDB控制台, 由PHP撰写而成。
    • Database Master — Windows的mongodb管理工具
    • RockMongo — 最好的PHP语言的MongoDB管理工具,轻量级, 支持多国语言.

    MongoDB 应用案例

    下面列举一些公司MongoDB的实际应用:

    • Craiglist上使用MongoDB的存档数十亿条记录。
    • FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
    • Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
    • bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
    • spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
    • Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
    • sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
    • etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
    • 纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
    • CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。

    什么是MongoDB ?

    MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

    在高负载的情况下,添加更多的节点,可以保证服务器性能。

    MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

    MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。


    主要特点

    • MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。
    • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
    • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
    • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
    • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
    • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
    • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
    • Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
    • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
    • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
    • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
    • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
    • MongoDB安装简单。

    历史

    • 2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。
    • 2012年05月23日,MongoDB2.1 开发分支发布了! 该版本采用全新架构,包含诸多增强。
    • 2012年06月06日,MongoDB 2.0.6 发布,分布式文档数据库。
    • 2013年04月23日,MongoDB 2.4.3 发布,此版本包括了一些性能优化,功能增强以及bug修复。
    • 2013年08月20日,MongoDB 2.4.6 发布。
    • 2013年11月01日,MongoDB 2.4.8 发布。
    • ……

    MongoDB 下载

    你可以在mongodb官网下载该安装包,地址为:https://www.mongodb.com/download-center#community。MonggoDB支持以下平台:

    • OS X 32-bit
    • OS X 64-bit
    • Linux 32-bit
    • Linux 64-bit
    • Windows 32-bit
    • Windows 64-bit
    • Solaris i86pc
    • Solaris 64

    语言支持

    MongoDB有官方的驱动如下:


    MongoDB 工具

    有几种可用于MongoDB的管理工具。

    监控

    MongoDB提供了网络和系统监控工具Munin,它作为一个插件应用于MongoDB中。

    Gangila是MongoDB高性能的系统监视的工具,它作为一个插件应用于MongoDB中。

    基于图形界面的开源工具 Cacti, 用于查看CPU负载, 网络带宽利用率,它也提供了一个应用于监控 MongoDB 的插件。

    GUI

    • Fang of Mongo – 网页式,由Django和jQuery所构成。
    • Futon4Mongo – 一个CouchDB Futon web的mongodb山寨版。
    • Mongo3 – Ruby写成。
    • MongoHub – 适用于OSX的应用程序。
    • Opricot – 一个基于浏览器的MongoDB控制台, 由PHP撰写而成。
    • Database Master — Windows的mongodb管理工具
    • RockMongo — 最好的PHP语言的MongoDB管理工具,轻量级, 支持多国语言.

    MongoDB 应用案例

    下面列举一些公司MongoDB的实际应用:

    • Craiglist上使用MongoDB的存档数十亿条记录。
    • FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
    • Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
    • bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
    • spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
    • Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
    • sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
    • etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
    • 纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
    • CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。

    Linux平台安装MongoDB

    MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包。

    下载地址:https://www.mongodb.com/download-center#community

    下载完安装包,并解压 tgz(以下演示的是 64 位 Linux上的安装) 。

    curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载 tar -zxvf mongodb-linux-x86_64-3.0.6.tgz # 解压 mv mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb # 将解压包拷贝到指定目录

    MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:

    export PATH=<mongodb-install-directory>/bin:$PATH

    <mongodb-install-directory> 为你 MongoDB 的安装路径。如本文的 /usr/local/mongodb 。

     


    创建数据库目录

    MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。

    以下实例中我们将data目录创建于根目录下(/)。

    注意:/data/db 是 MongoDB 默认的启动的数据库路径(--dbpath)。

    mkdir -p /data/db

     


    命令行中运行 MongoDB 服务

    你可以再命令行中执行mongo安装目录中的bin目录执行mongod命令来启动mongdb服务。

    注意:如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定。

    $ ./mongod
    2015-09-25T16:39:50.549+0800 I JOURNAL [initandlisten] journal dir=/data/db/journal 2015-09-25T16:39:50.550+0800 I JOURNAL [initandlisten] recover : no journal files present, no recovery needed 2015-09-25T16:39:50.869+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.16 2015-09-25T16:39:51.206+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.52 2015-09-25T16:39:52.775+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 7.7

     


    MongoDB后台管理 Shell

    如果你需要进入MongoDB后台管理,你需要先打开mongodb装目录的下的bin目录,然后执行mongo命令文件。

    MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。

    当你进入mongoDB后台后,它默认会链接到 test 文档(数据库):

    $ cd /usr/local/mongodb/bin $ ./mongo MongoDB shell version: 3.0.6 connecting to: test Welcome to the MongoDB shell. ……

    由于它是一个JavaScript shell,您可以运行一些简单的算术运算:

    > 2+2 4 > 3+6 9

    现在让我们插入一些简单的数据,并对插入的数据进行检索:

    > db.runoob.insert({x:10}) WriteResult({ "nInserted" : 1 }) > db.runoob.find() { "_id" : ObjectId("5604ff74a274a611b0c990aa"), "x" : 10 } >

    第一个命令将数字 10 插入到 runoob 集合的 x 字段中。

     


    MongoDb web 用户界面

    MongoDB 提供了简单的 HTTP 用户界面。 如果你想启用该功能,需要在启动的时候指定参数 --rest 。

    $ ./mongod --dbpath=/data/db --rest

    MongoDB 的 Web 界面访问端口比服务的端口多1000。

    如果你的MongoDB运行端口使用默认的27017,你可以在端口号为28017访问web用户界面,即地址为:http://localhost:28017。

     

    Mac OSX 平台安装 MongoDB

    MongoDB 提供了 OSX 平台上 64 位的安装包,你可以在官网下载安装包。

    下载地址:https://www.mongodb.com/download-center#community

     

    从 MongoDB 3.0 版本开始只支持 OS X 10.7 (Lion) 版本及更新版本的系统。

     

    接下来我们使用 curl 命令来下载安装:

    # 进入 /usr/local
    cd /usr/local
    
    # 下载
    sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.4.2.tgz
    
    # 解压
    sudo tar -zxvf mongodb-osx-x86_64-3.4.2.tgz
    
    # 重命名为 mongodb 目录
    
    sudo mv mongodb-osx-x86_64-3.4.2 mongodb
    

    安装完成后,我们可以把 MongoDB 的二进制命令文件目录(安装目录/bin)添加到 PATH 路径中:

    export PATH=/usr/local/mongodb/bin:$PATH
    

    使用 brew 安装

    此外你还可以使用 OSX 的 brew 来安装 mongodb:

    sudo brew install mongodb
    

    如果要安装支持 TLS/SSL 命令如下:

    sudo brew install mongodb --with-openssl
    

    安装最新开发版本:

    sudo brew install mongodb --devel

    运行 MongoDB

    1、首先我们创建一个数据库存储目录 /data/db:

    sudo mkdir -p /data/db
    

    启动 mongodb,默认数据库目录即为 /data/db:

    sudo mongod
    
    # 如果没有创建全局路径 PATH,需要进入以下目录
    cd /usr/local/mongodb/bin
    sudo ./mongod
    

    再打开一个终端进入执行以下命令:

    $ cd /usr/local/mongodb/bin 
    $ ./mongo
    MongoDB shell version v3.4.2
    connecting to: mongodb://127.0.0.1:27017
    MongoDB server version: 3.4.2
    Welcome to the MongoDB shell.
    ……
    > 1 + 1
    2
    > 
    

    注意:如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定。

     

     

    MongoDB 概念解析

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

    下表将帮助您更容易理解Mongo中的一些概念:

    SQL术语/概念MongoDB术语/概念解释/说明
    databasedatabase数据库
    tablecollection数据库表/集合
    rowdocument数据记录行/文档
    columnfield数据字段/域
    indexindex索引
    table joins 表连接,MongoDB不支持
    primary keyprimary key主键,MongoDB自动将_id字段设置为主键

    通过下图实例,我们也可以更直观的的了解Mongo中的一些概念:


    数据库

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

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

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

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

    $ ./mongo
    MongoDB shell version: 3.0.6 connecting to: test > show dbs local 0.078GB test 0.078GB >

    执行 "db" 命令可以显示当前数据库对象或集合。

    $ ./mongo
    MongoDB shell version: 3.0.6 connecting to: test > db test >

    运行"use"命令,可以连接到一个指定的数据库。

    > use local switched to db local > db local >

    以上实例命令中,"local" 是你要链接的数据库。

    在下一个章节我们将详细讲解MongoDB中命令的使用。

    数据库也通过名字来标识。数据库名可以是满足以下条件的任意UTF-8字符串。

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

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

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

    文档

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

    一个简单的文档例子如下:

    {"site":"www.runoob.com", "name":"菜鸟教程"}

    下表列出了 RDBMS 与 MongoDB 对应的术语:

    RDBMSMongoDB
    数据库数据库
    表格集合
    文档
    字段
    表联合嵌入文档
    主键主键 (MongoDB 提供了 key 为 _id )
    数据库服务和客户端
    Mysqld/Oraclemongod
    mysql/sqlplusmongo

    需要注意的是:

    1. 文档中的键/值对是有序的。
    2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
    3. MongoDB区分类型和大小写。
    4. MongoDB的文档不能有重复的键。
    5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

    文档键命名规范:

    • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
    • .和$有特别的意义,只有在特定环境下才能使用。
    • 以下划线"_"开头的键是保留的(不是严格要求的)。

    集合

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

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

     

    比如,我们可以将以下不同数据结构的文档插入到集合中:

    {"site":"www.baidu.com"} {"site":"www.google.com","name":"Google"} {"site":"www.runoob.com","name":"菜鸟教程","num":5}

    当第一个文档插入时,集合就会被创建。

    合法的集合名

    • 集合名不能是空字符串""。
    • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
    • 集合名不能以"system."开头,这是为系统集合保留的前缀。
    • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。 

    如下实例:

    db.col.findOne()

    capped collections

    Capped collections 就是固定大小的collection。

    它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似。

    Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。

     

    要注意的是指定的存储大小包含了数据库的头信息。

     

    db.createCollection("mycoll", {capped:true, size:100000})
    • 在capped collection中,你能添加新的对象。
    • 能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
    • 数据库不允许进行删除。使用drop()方法删除collection所有的行。
    • 注意: 删除之后,你必须显式的重新创建这个collection。
    • 在32bit机器中,capped collection最大存储为1e9( 1X109)个字节。

    元数据

    数据库的信息是存储在集合中。它们使用了系统的命名空间:

    dbname.system.*

    在MongoDB数据库中名字空间 <dbname>.system.* 是包含多种系统信息的特殊集合(Collection),如下:

    集合命名空间描述
    dbname.system.namespaces列出所有名字空间。
    dbname.system.indexes列出所有索引。
    dbname.system.profile包含数据库概要(profile)信息。
    dbname.system.users列出所有可访问数据库的用户。
    dbname.local.sources包含复制对端(slave)的服务器信息和状态。

    对于修改系统集合中的对象有如下限制。

    在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。

    {{system.users}}是可修改的。 {{system.profile}}是可删除的。


    MongoDB 数据类型

    下表为MongoDB中常用的几种数据类型。

    数据类型描述
    String字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
    Integer整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
    Boolean布尔值。用于存储布尔值(真/假)。
    Double双精度浮点值。用于存储浮点值。
    Min/Max keys将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
    Arrays用于将数组或列表或多个值存储为一个键。
    Timestamp时间戳。记录文档修改或添加的具体时间。
    Object用于内嵌文档。
    Null用于创建空值。
    Symbol符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
    Date日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
    Object ID对象 ID。用于创建文档的 ID。
    Binary Data二进制数据。用于存储二进制数据。
    Code代码类型。用于在文档中存储 JavaScript 代码。
    Regular expression正则表达式类型。用于存储正则表达式。

    MongoDB - 连接

    在本教程我们将讨论 MongoDB 的不同连接方式。

    启动 MongoDB 服务

    在前面的教程中,我们已经讨论了如何启动 MongoDB 服务,你只需要在 MongoDB 安装目录的 bin 目录下执行 mongod 即可。

    执行启动操作后,mongodb 在输出一些必要信息后不会输出任何信息,之后就等待连接的建立,当连接被建立后,就会开始打印日志信息。

    你可以使用 MongoDB shell 来连接 MongoDB 服务器。你也可以使用 PHP 来连接 MongoDB。本教程我们会使用 MongoDB shell 来连接 Mongodb 服务,之后的章节我们将会介绍如何通过php 来连接MongoDB服务。

    标准 URI 连接语法:

    mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
    
    • mongodb:// 这是固定的格式,必须要指定。

    • username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库

    • host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。

    • portX 可选的指定端口,如果不填,默认为27017

    • /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。

    • ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开

    标准的连接格式包含了多个选项(options),如下所示:

    选项描述
    replicaSet=name验证replica set的名称。 Impliesconnect=replicaSet.
    slaveOk=true|false
    • true:在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。
    • false: 在 connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet 模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。
    safe=true|false
    • true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS).
    false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。
    w=n驱动添加 { w : n } 到getLastError命令. 应用于safe=true。
    wtimeoutMS=ms驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
    fsync=true|false
    • true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true.
    • false: 驱动不会添加到getLastError命令中。
    journal=true|false如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
    connectTimeoutMS=ms可以打开连接的时间。
    socketTimeoutMS=ms发送和接受sockets的时间。

    实例

    使用默认端口来连接 MongoDB 的服务。

    mongodb://localhost

    通过 shell 连接 MongoDB 服务:

    $ ./mongo
    MongoDB shell version: 3.0.6
    connecting to: test
    ... 
    

    这时候你返回查看运行 ./mongod 命令的窗口,可以看到是从哪里连接到MongoDB的服务器,您可以看到如下信息:

    ……省略信息……
    2015-09-25T17:22:27.336+0800 I CONTROL  [initandlisten] allocator: tcmalloc
    2015-09-25T17:22:27.336+0800 I CONTROL  [initandlisten] options: { storage: { dbPath: "/data/db" } }
    2015-09-25T17:22:27.350+0800 I NETWORK  [initandlisten] waiting for connections on port 27017
    2015-09-25T17:22:36.012+0800 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:37310 #1 (1 connection now open)  # 该行表明一个来自本机的连接
    
    ……省略信息……
    

    MongoDB 连接命令格式

    使用用户名和密码连接到 MongoDB 服务器,你必须使用 'username:password@hostname/dbname' 格式,'username'为用户名,'password' 为密码。

    使用用户名和密码连接登陆到默认数据库:

    $ ./mongo
    MongoDB shell version: 3.0.6
    connecting to: test
    

    使用用户 admin 使用密码 123456 连接到本地的 MongoDB 服务上。输出结果如下所示:

    > mongodb://admin:123456@localhost/
    ... 
    

    使用用户名和密码连接登陆到指定数据库,格式如下:

    mongodb://admin:123456@localhost/test

    更多连接实例

    连接本地数据库服务器,端口是默认的。

    mongodb://localhost

    使用用户名fred,密码foobar登录localhost的admin数据库。

    mongodb://fred:foobar@localhost

    使用用户名fred,密码foobar登录localhost的baz数据库。

    mongodb://fred:foobar@localhost/baz

    连接 replica pair, 服务器1为example1.com服务器2为example2。

    mongodb://example1.com:27017,example2.com:27017

    连接 replica set 三台服务器 (端口 27017, 27018, 和27019):

    mongodb://localhost,localhost:27018,localhost:27019

    连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。

    mongodb://host1,host2,host3/?slaveOk=true

    直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。

    mongodb://host1,host2,host3/?connect=direct;slaveOk=true

    当你的连接服务器有优先级,还需要列出所有服务器,你可以使用上述连接方式。

    安全模式连接到localhost:

    mongodb://localhost/?safe=true

    以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。

    mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000

    MongoDB 创建数据库

    语法

    MongoDB 创建数据库的语法格式如下:

    use DATABASE_NAME

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

    实例

    以下实例我们创建了数据库 runoob:

    > use runoob
    switched to db runoob
    > db
    runoob
    > 
    

    如果你想查看所有数据库,可以使用 show dbs 命令:

    > show dbs
    local  0.078GB
    test   0.078GB
    > 
    

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

    > db.runoob.insert({"name":"菜鸟教程"})
    WriteResult({ "nInserted" : 1 })
    > show dbs
    local   0.078GB
    runoob  0.078GB
    test    0.078GB
    > 
    

    MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。

     

     

    MongoDB 删除数据库

    语法

    MongoDB 删除数据库的语法格式如下:

    db.dropDatabase()

    删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。

    实例

    以下实例我们删除了数据库 runoob。

    首先,查看所有数据库:

    > show dbs
    local   0.078GB runoob 0.078GB test 0.078GB

    接下来我们切换到数据库 runoob:

    > use runoob
    switched to db runoob
    >

    执行删除命令:

    > db.dropDatabase() { "dropped" : "runoob", "ok" : 1 }

    最后,我们再通过 show dbs 命令数据库是否删除成功:

    > show dbs
    local  0.078GB test 0.078GB >

    删除集合

    集合删除语法格式如下:

    db.collection.drop()

    以下实例删除了 runoob 数据库中的集合 site:

    > use runoob
    switched to db runoob
    > show tables site > db.site.drop() true > show tables >

    MongoDB 插入文档

    本章节中我们将向大家介绍如何将数据插入到MongoDB的集合中。

    文档的数据结构和JSON基本一样。

    所有存储在集合中的数据都是BSON格式。

    BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。

    插入文档

    MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:

    db.COLLECTION_NAME.insert(document)

    实例

    以下文档可以存储在 MongoDB 的 runoob 数据库 的 col 集合中:

    >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 } >

    我们也可以将数据定义为一个变量,如下所示:

     

    > document=({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 });

    执行后显示结果如下:

    {
            "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

    执行插入操作:

    > db.col.insert(document) WriteResult({ "nInserted" : 1 }) >

    插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。

     笔记列表

    1.    二少

        272***623@qq.com

         参考地址

      3.2 版本后还有以下几种语法可用于插入文档:

      •  db.collection.insertOne():向指定集合中插入一条文档数据
      •  db.collection.insertMany():向指定集合中插入多条文档数据
      #  插入单条数据
      
      > var document = db.collection.insertOne({"a": 3}) > document { "acknowledged" : true, "insertedId" : ObjectId("571a218011a82a1d94c02333") } # 插入多条数据 > var res = db.collection.insertMany([{"b": 3}, {'c': 4}]) > res { "acknowledged" : true, "insertedIds" : [ ObjectId("571a22a911a82a1d94c02337"), ObjectId("571a22a911a82a1d94c02338") ] }

      MongoDB 更新文档

      MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。


      update() 方法

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

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

      参数说明:

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

      实例

      我们在集合 col 中插入如下数据:

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

      接着我们通过 update() 方法来更新标题(title):

      >db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 输出信息 > db.col.find().pretty() { "_id" : ObjectId("56064f89ade2f21f36b03136"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 } >

      可以看到标题(title)由原来的 "MongoDB 教程" 更新为了 "MongoDB"。

      以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。

      >db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})

      save() 方法

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

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

      参数说明:

      • document : 文档数据。
      • writeConcern :可选,抛出异常的级别。

      实例

      以下实例中我们替换了 _id 为 56064f89ade2f21f36b03136 的文档数据:

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

      替换成功后,我们可以通过 find() 命令来查看替换后的数据

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

      更多实例

      只更新第一条记录:

      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 );
       

      MongoDB 删除文档

      在前面的几个章节中我们已经学习了MongoDB中如何为集合添加数据和更新数据。在本章节中我们将继续学习MongoDB集合的删除。

      MongoDB remove()函数是用来移除集合中的数据。

      MongoDB数据更新可以使用update()函数。在执行remove()函数前先执行find()命令来判断执行的条件是否正确,这是一个比较好的习惯。

      语法

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

      db.collection.remove( <query>, <justOne> )

      如果你的 MongoDB 是 2.6 版本以后的,语法格式如下:

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

      参数说明:

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

      实例

      以下文档我们执行两次插入操作:

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

      使用 find() 函数查询数据:

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

      接下来我们移除 title 为 'MongoDB 教程' 的文档:

      >db.col.remove({'title':'MongoDB 教程'}) WriteResult({ "nRemoved" : 2 }) # 删除了两条数据 >db.col.find() …… # 没有数据

      如果你只想删除第一条找到的记录可以设置 justOne 为 1,如下所示:

      >db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)

      如果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):

      >db.col.remove({}) >db.col.find() >


      MongoDB 查询文档

      MongoDB 查询文档使用 find() 方法。

      find() 方法以非结构化的方式来显示所有文档。

      语法

      MongoDB 查询数据的语法格式如下:

      db.collection.find(query, projection)
      • query :可选,使用查询操作符指定查询条件
      • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

      如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

      >db.col.find().pretty()
      

      pretty() 方法以格式化的方式来显示所有文档。

      实例

      以下实例我们查询了集合 col 中的数据:

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

      除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。


      MongoDB 与 RDBMS Where 语句比较

      如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:

      操作格式范例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

      MongoDB AND 条件

      MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,及常规 SQL 的 AND 条件。

      语法格式如下:

      >db.col.find({key1:value1, key2:value2}).pretty()
      

      实例

      以下实例通过 by 和 title 键来查询 菜鸟教程 中 MongoDB 教程 的数据

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

      以上实例中类似于 WHERE 语句:WHERE by='菜鸟教程' AND title='MongoDB 教程'


      MongoDB OR 条件

      MongoDB OR 条件语句使用了关键字 $or,语法格式如下:

      >db.col.find(
         {
            $or: [
      	     {key1: value1}, {key2:value2}
            ]
         }
      ).pretty()
      

      实例

      以下实例中,我们演示了查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。

      >db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
      {
              "_id" : ObjectId("56063f17ade2f21f36b03133"),
              "title" : "MongoDB 教程",
              "description" : "MongoDB 是一个 Nosql 数据库",
              "by" : "菜鸟教程",
              "url" : "http://www.runoob.com",
              "tags" : [
                      "mongodb",
                      "database",
                      "NoSQL"
              ],
              "likes" : 100
      }
      >
      

      AND 和 OR 联合使用

      以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为: 'where likes>50 AND (by = '菜鸟教程' OR title = 'MongoDB 教程')'

      >db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
      {
              "_id" : ObjectId("56063f17ade2f21f36b03133"),
              "title" : "MongoDB 教程",
              "description" : "MongoDB 是一个 Nosql 数据库",
              "by" : "菜鸟教程",
              "url" : "http://www.runoob.com",
              "tags" : [
                      "mongodb",
                      "database",
                      "NoSQL"
              ],
              "likes" : 100
      }

      MongoDB 条件操作符


      描述

      条件操作符用于比较两个表达式并从mongoDB集合中获取数据。

      在本章节中,我们将讨论如何在MongoDB中使用条件操作符。

      MongoDB中条件操作符有:

      • (>) 大于 - $gt
      • (<) 小于 - $lt
      • (>=) 大于等于 - $gte
      • (<= ) 小于等于 - $lte

      我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。

      为了方便测试,我们可以先使用以下命令清空集合 "col" 的数据:

      db.col.remove({})

      插入以下数据

      >db.col.insert({ title: 'PHP 教程', description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['php'], likes: 200 })

      >db.col.insert({title: 'Java 教程', description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['java'], likes: 150 })

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

      使用find()命令查看数据:

      > db.col.find() { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }

      MongoDB (>) 大于操作符 - $gt

      如果你想获取 "col" 集合中 "likes" 大于 100 的数据,你可以使用以下命令:

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

      类似于SQL语句:

      Select * from col where likes > 100;

      输出结果:

      > db.col.find({"likes" : {$gt : 100}}) { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } >

      MongoDB(>=)大于等于操作符 - $gte

      如果你想获取"col"集合中 "likes" 大于等于 100 的数据,你可以使用以下命令:

      db.col.find({likes : {$gte : 100}})

      类似于SQL语句:

      Select * from col where likes >=100;

      输出结果:

       

      > db.col.find({likes : {$gte : 100}}) { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 } >

      MongoDB (<) 小于操作符 - $lt

      如果你想获取"col"集合中 "likes" 小于 150 的数据,你可以使用以下命令:

      db.col.find({likes : {$lt : 150}})

      类似于SQL语句:

      Select * from col where likes < 150;

      输出结果:

       

      > db.col.find({likes : {$lt : 150}}) { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }

      MongoDB (<=) 小于操作符 - $lte

      如果你想获取"col"集合中 "likes" 小于等于 150 的数据,你可以使用以下命令:

      db.col.find({likes : {$lte : 150}})

      类似于SQL语句:

      Select * from col where likes <= 150;

      输出结果:

      > db.col.find({likes : {$lte : 150}}) { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }

      MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt

      如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:

      db.col.find({likes : {$lt :200, $gt : 100}})

      类似于SQL语句:

      Select * from col where likes>100 AND likes<200;

      输出结果:

       

      > db.col.find({likes : {$lt :200, $gt : 100}}) { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } >

       笔记列表

      1.    Mrt.L

          903***165@qq.com

        一些简写说明:

        $gt -------- greater than  >
        
        $gte --------- gt equal >= $lt -------- less than < $lte --------- lt equal <= $ne ----------- not equal != $eq -------- equal =

     

    MongoDB $type 操作符

     

    描述

    在本章节中,我们将继续讨论MongoDB中条件操作符 $type。

    $type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。

    MongoDB 中可以使用的类型如下表所示:

    类型数字备注
    Double1 
    String2 
    Object3 
    Array4 
    Binary data5 
    Undefined6已废弃。
    Object id7 
    Boolean8 
    Date9 
    Null10 
    Regular Expression11 
    JavaScript13 
    Symbol14 
    JavaScript (with scope)15 
    32-bit integer16 
    Timestamp17 
    64-bit integer18 
    Min key255Query with -1.
    Max key127 

    我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。

    简单的集合"col":

    >db.col.insert({
        title: 'PHP 教程', 
        description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。',
        by: '菜鸟教程',
        url: 'http://www.runoob.com',
        tags: ['php'],
        likes: 200
    })
    

     

    >db.col.insert({title: 'Java 教程', 
        description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。',
        by: '菜鸟教程',
        url: 'http://www.runoob.com',
        tags: ['java'],
        likes: 150
    })
    

     

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

    使用find()命令查看数据:

    > db.col.find()
    { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
    { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
    { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
    

     

    MongoDB 操作符 - $type 实例

    如果想获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:

    db.col.find({"title" : {$type : 2}})

    输出结果为:

    { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
    { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
    { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }


    MongoDB Limit与Skip方法


    MongoDB Limit() 方法

    如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。

    语法

    limit()方法基本语法如下所示:

    >db.COLLECTION_NAME.find().limit(NUMBER)

    实例

    集合 col 中的数据如下:

    { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }

    以上实例为显示查询文档中的两条记录:

    > db.col.find({},{"title":1,_id:0}).limit(2) { "title" : "PHP 教程" } { "title" : "Java 教程" } >

    注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。


    MongoDB Skip() 方法

    我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。

    语法

    skip() 方法脚本语法格式如下:

    >db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

    实例

    以上实例只会显示第二条文档数据

    >db.col.find({},{"title":1,_id:0}).limit(1).skip(1) { "title" : "Java 教程" } >

    注:skip()方法默认参数为 0 。

     笔记列表

    1.  

      db.col.find({},{"title":1,_id:0}).limit(2)

      补充说明:

      • 第一个 {} 放 where 条件,为空表示返回集合中所有文档。
      • 第二个 {} 指定那些列显示和不显示 (0表示不显示 1表示显示)。
       
    2.  

      想要读取从 10 条记录后 100 条记录,相当于 sql 中limit (10,100)。

      > db.COLLECTION_NAME.find().skip(10).limit(100)

      以上实例在集合中跳过前面 10 条返回 100 条数据。

      skip 和 limit 结合就能实现分页。

       
    3. 当查询时同时使用sort,skip,limit,无论位置先后,最先执行顺序 sort再skip再limit。

       

       

      MongoDB 排序


      MongoDB sort()方法

      在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。

      语法

      sort()方法基本语法如下所示:

      >db.COLLECTION_NAME.find().sort({KEY:1})
      

      实例

      col 集合中的数据如下:

      { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
      { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
      { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
      

      以下实例演示了 col 集合中的数据按字段 likes 的降序排列:

      >db.col.find({},{"title":1,_id:0}).sort({"likes":-1})
      { "title" : "PHP 教程" }
      { "title" : "Java 教程" }
      { "title" : "MongoDB 教程" }


      MongoDB 索引

      索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。

      这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

      索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构


      ensureIndex() 方法

      MongoDB使用 ensureIndex() 方法来创建索引。

      语法

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

      >db.COLLECTION_NAME.ensureIndex({KEY:1})

      语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。

      实例

      >db.col.ensureIndex({"title":1}) >

      ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。

      >db.col.ensureIndex({"title":1,"description":-1}) >

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

      ParameterTypeDescription
      backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
      uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
      namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
      dropDupsBoolean在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
      sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
      expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
      vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
      weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
      default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
      language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

      实例

      在后台创建索引:

      db.values.ensureIndex({open: 1, close: 1}, {background: true})

      通过在创建索引时加background:true 的选项,让创建工作在后台执行

      MongoDB 聚合

      MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。


      aggregate() 方法

      MongoDB中聚合的方法使用aggregate()。

      语法

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

      >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

      实例

      集合中的数据如下:

      {
         _id: ObjectId(7df78ad8902c) title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 }, { _id: ObjectId(7df78ad8902d) title: 'NoSQL Overview', description: 'No sql database is very fast', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 10 }, { _id: ObjectId(7df78ad8902e) title: 'Neo4j Overview', description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 },

      现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:

      > db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) { "result" : [ { "_id" : "runoob.com", "num_tutorial" : 2 }, { "_id" : "Neo4j", "num_tutorial" : 1 } ], "ok" : 1 } >

      以上实例类似sql语句: select by_user, count(*) from mycol group by by_user

      在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。

      下表展示了一些聚合的表达式:

      表达式描述实例
      $sum计算总和。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
      $avg计算平均值db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
      $min获取集合中所有文档对应值得最小值。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
      $max获取集合中所有文档对应值得最大值。db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
      $push在结果文档中插入值到一个数组中。db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
      $addToSet在结果文档中插入值到一个数组中,但不创建副本。db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
      $first根据资源文档的排序获取第一个文档数据。db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
      $last根据资源文档的排序获取最后一个文档数据db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

      管道的概念

      管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

      MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

      表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

      这里我们介绍一下聚合框架中常用的几个操作:

      • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
      • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
      • $limit:用来限制MongoDB聚合管道返回的文档数。
      • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
      • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
      • $group:将集合中的文档分组,可用于统计结果。
      • $sort:将输入文档排序后输出。
      • $geoNear:输出接近某一地理位置的有序文档。

      管道操作符实例

      1、$project实例

       

      db.article.aggregate( { $project : { title : 1 , author : 1 , }} );

      这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:

      db.article.aggregate( { $project : { _id : 0 , title : 1 , author : 1 }});

      2.$match实例

      db.articles.aggregate( [ { $match : { score : { $gt : 70, $lte : 90 } } }, { $group: { _id: null, count: { $sum: 1 } } } ] );

      $match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。

      3.$skip实例

      db.article.aggregate( { $skip : 5 });

      经过$skip管道操作符处理后,前五个文档被"过滤"掉。

       笔记列表

      1.  

        db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])

        以上实例类似sql语句:

        select by_user as _id, count(*) as num_tutorial from mycol group by by_user
         
      2.  

        db.articles.aggregate({ $project : { title: 2, by_user: 1, } })

        这样子也是可行的。也就是说非0也可以进行表示显示该字段,负数也可以表示显示该字段。

         

        MongoDB 复制(副本集)

        MongoDB复制是将数据同步在多个服务器的过程。

        复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。

        复制还允许您从硬件故障和服务中断中恢复数据。


        什么是复制?

        • 保障数据的安全性
        • 数据高可用性 (24*7)
        • 灾难恢复
        • 无需停机维护(如备份,重建索引,压缩)
        • 分布式读取数据

        MongoDB复制原理

        mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。

        mongodb各个节点常见的搭配方式为:一主一从、一主多从。

        主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。

        MongoDB复制结构图如下所示:

        MongoDB复制结构图

        以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。

        副本集特征:

        • N 个节点的集群
        • 任何节点可作为主节点
        • 所有写入操作都在主节点上
        • 自动故障转移
        • 自动恢复

        MongoDB副本集设置

        在本教程中我们使用同一个MongoDB来做MongoDB主从的实验, 操作步骤如下:

        1、关闭正在运行的MongoDB服务器。

        现在我们通过指定 --replSet 选项来启动mongoDB。--replSet 基本语法格式如下:

        mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
        

        实例

        mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
        

        以上实例会启动一个名为rs0的MongoDB实例,其端口号为27017。

        启动后打开命令提示框并连接上mongoDB服务。

        在Mongo客户端使用命令rs.initiate()来启动一个新的副本集。

        我们可以使用rs.conf()来查看副本集的配置

        查看副本集状态使用 rs.status() 命令


        副本集添加成员

        添加副本集的成员,我们需要使用多条服务器来启动mongo服务。进入Mongo客户端,并使用rs.add()方法来添加副本集的成员。

        语法

        rs.add() 命令基本语法格式如下:

        >rs.add(HOST_NAME:PORT)
        

        实例

        假设你已经启动了一个名为mongod1.net,端口号为27017的Mongo服务。 在客户端命令窗口使用rs.add() 命令将其添加到副本集中,命令如下所示:

        >rs.add("mongod1.net:27017")
        >
        

        MongoDB中你只能通过主节点将Mongo服务添加到副本集中, 判断当前运行的Mongo服务是否为主节点可以使用命令db.isMaster() 。

        MongoDB的副本集与我们常见的主从有所不同,主从在主机宕机后所有服务将停止,而副本集在主机宕机后,副本会接管主节点成为主节点,不会出现宕机的情况。

         

         

        MongoDB 分片


        分片

        在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。

        当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。


        为什么使用分片

        • 复制所有的写入操作到主节点
        • 延迟的敏感数据会在主节点查询
        • 单个副本集限制在12个节点
        • 当请求量巨大时会出现内存不足。
        • 本地磁盘不足
        • 垂直扩展价格昂贵

        MongoDB分片

        下图展示了在MongoDB中使用分片集群结构分布:

        上图中主要有如下所述三个主要组件:

        • Shard:

          用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障

        • Config Server:

          mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。

        • Query Routers:

          前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。


        分片实例

        分片结构端口分布如下:

        Shard Server 127020 Shard Server 227021 Shard Server 327022 Shard Server 427023 Config Server 27100 Route Process40000

        步骤一:启动Shard Server

        [root@100 /]# mkdir -p /www/mongoDB/shard/s0 [root@100 /]# mkdir -p /www/mongoDB/shard/s1 [root@100 /]# mkdir -p /www/mongoDB/shard/s2 [root@100 /]# mkdir -p /www/mongoDB/shard/s3 [root@100 /]# mkdir -p /www/mongoDB/shard/log [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork .... [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27023 --dbpath=/www/mongoDB/shard/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork

        步骤二: 启动Config Server

        [root@100 /]# mkdir -p /www/mongoDB/shard/config [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork

        注意:这里我们完全可以像启动普通mongodb服务一样启动,不需要添加—shardsvr和configsvr参数。因为这两个参数的作用就是改变启动端口的,所以我们自行指定了端口就可以。

        步骤三: 启动Route Process

        /usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500

        mongos启动参数中,chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB.

        步骤四: 配置Sharding

        接下来,我们使用MongoDB Shell登录到mongos,添加Shard节点

        [root@100 shard]# /usr/local/mongoDB/bin/mongo admin --port 40000 MongoDB shell version: 2.0.7 connecting to: 127.0.0.1:40000/admin mongos> db.runCommand({ addshard:"localhost:27020" }) { "shardAdded" : "shard0000", "ok" : 1 } ...... mongos> db.runCommand({ addshard:"localhost:27029" }) { "shardAdded" : "shard0009", "ok" : 1 } mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库 { "ok" : 1 } mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}}) { "collectionsharded" : "test.log", "ok" : 1 }

        步骤五: 程序代码内无需太大更改,直接按照连接普通的mongo数据库那样,将数据库连接接入接口40000

        MongoDB 备份(mongodump)与恢复(mongorestore)


        MongoDB数据备份

        在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。

        mongodump命令可以通过参数指定导出的数据量级转存的服务器。

        语法

        mongodump命令脚本语法如下:

        >mongodump -h dbhost -d dbname -o dbdirectory
        
        • -h:

          MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017

        • -d:

          需要备份的数据库实例,例如:test

        • -o:

          备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

        实例

        在本地使用 27017 启动你的mongod服务。打开命令提示符窗口,进入MongoDB安装目录的bin目录输入命令mongodump:

        >mongodump
        

        执行以上命令后,客户端会连接到ip为 127.0.0.1 端口号为 27017 的MongoDB服务上,并备份所有数据到 bin/dump/ 目录中。命令输出结果如下:

        MongoDB数据备份

        mongodump 命令可选参数列表如下所示:

        语法描述实例
        mongodump --host HOST_NAME --port PORT_NUMBER该命令将备份所有MongoDB数据mongodump --host w3cschool.cc --port 27017
        mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY mongodump --dbpath /data/db/ --out /data/backup/
        mongodump --collection COLLECTION --db DB_NAME该命令将备份指定数据库的集合。mongodump --collection mycol --db test

        MongoDB数据恢复

        mongodb使用 mongorestore 命令来恢复备份的数据。

        语法

        mongorestore命令脚本语法如下:

        >mongorestore -h <hostname><:port> -d dbname <path>
        
        • --host <:port>, -h <:port>:

          MongoDB所在服务器地址,默认为: localhost:27017

        • --db , -d :

          需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2

        • --drop:

          恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!

        • <path>:

          mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。

          你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录。

        • --dir:

          指定备份的目录

          你不能同时指定 <path> 和 --dir 选项。

        接下来我们执行以下命令:

        >mongorestore
        

        执行以上命令输出结果如下:

        MongoDB数据恢复

         

         

        MongoDB 监控

        在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能。这样在大流量得情况下可以很好的应对并保证MongoDB正常运作。

        MongoDB中提供了mongostat 和 mongotop 两个命令来监控MongoDB的运行情况。


        mongostat 命令

        mongostat是mongodb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。

        启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat命令,如下所示:

        D:\set up\mongodb\bin>mongostat
        

        以上命令输出结果如下:

        mongotop 命令

        mongotop也是mongodb下的一个内置工具,mongotop提供了一个方法,用来跟踪一个MongoDB的实例,查看哪些大量的时间花费在读取和写入数据。 mongotop提供每个集合的水平的统计数据。默认情况下,mongotop返回值的每一秒。

        启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongotop命令,如下所示:

        D:\set up\mongodb\bin>mongotop
        

        以上命令执行输出结果如下:

        带参数实例

         E:\mongodb-win32-x86_64-2.2.1\bin>mongotop 10
        

        后面的10是<sleeptime>参数 ,可以不使用,等待的时间长度,以秒为单位,mongotop等待调用之间。通过的默认mongotop返回数据的每一秒。

         E:\mongodb-win32-x86_64-2.2.1\bin>mongotop --locks
        

        报告每个数据库的锁的使用中,使用mongotop - 锁,这将产生以下输出:

        输出结果字段说明:

        • ns:

          包含数据库命名空间,后者结合了数据库名称和集合。

        • db:

          包含数据库的名称。名为 . 的数据库针对全局锁定,而非特定数据库。

        • total:

          mongod花费的时间工作在这个命名空间提供总额。

        • read:

          提供了大量的时间,这mongod花费在执行读操作,在此命名空间。

        • write:

          提供这个命名空间进行写操作,这mongod花了大量的时间。

         

        MongoDB Java

        环境配置

        在 Java 程序中如果要使用 MongoDB,你需要确保已经安装了 Java 环境及 MongoDB JDBC 驱动。

        本章节实例时候 Mongo 3.x 以上版本。

        你可以参考本站的Java教程来安装Java程序。现在让我们来检测你是否安装了 MongoDB JDBC 驱动。


        连接数据库

        连接数据库,你需要指定数据库名称,如果指定的数据库不存在,mongo会自动创建数据库。

        连接数据库的Java代码如下:

        import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }

        现在,让我们来编译运行程序并连接到数据库 mycol。

        你可以根据你的实际环境改变 MongoDB JDBC 驱动的路径。

        本实例将 MongoDB JDBC 启动包 mongo-java-driver-3.2.2.jar 放在本地目录下:

        $ javac -cp .:mongo-java-driver-3.2.2.jar MongoDBJDBC.java $ java -cp .:mongo-java-driver-3.2.2.jar MongoDBJDBC Connect to database successfully Authentication: true

        本实例中 Mongo 数据库无需用户名密码验证。如果你的 Mongo 需要验证用户名及密码,可以使用以下代码:

        import java.util.ArrayList; import java.util.List; import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC { public static void main(String[] args){ try { //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址  //ServerAddress()两个参数分别为 服务器地址 和 端口  ServerAddress serverAddress = new ServerAddress("localhost",27017); List<ServerAddress> addrs = new ArrayList<ServerAddress>(); addrs.add(serverAddress); //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码  MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray()); List<MongoCredential> credentials = new ArrayList<MongoCredential>(); credentials.add(credential); //通过连接认证获取MongoDB连接  MongoClient mongoClient = new MongoClient(addrs,credentials); //连接到数据库  MongoDatabase mongoDatabase = mongoClient.getDatabase("databaseName"); System.out.println("Connect to database successfully"); } catch (Exception e) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }

        创建集合

        我们可以使用 com.mongodb.client.MongoDatabase 类中的createCollection()来创建集合

        代码片段如下:

        import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); mongoDatabase.createCollection("test"); System.out.println("集合创建成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }

        编译运行以上程序,输出结果如下:

        Connect to database successfully
        集合创建成功

        获取集合

        我们可以使用com.mongodb.client.MongoDatabase类的 getCollection() 方法来获取一个集合

        代码片段如下:

        import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }

        编译运行以上程序,输出结果如下:

        Connect to database successfully
        集合 test 选择成功

        插入文档

        我们可以使用com.mongodb.client.MongoCollection类的 insertMany() 方法来插入一个文档

        代码片段如下:

        import java.util.ArrayList; import java.util.List; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); //插入文档  /** * 1. 创建文档 org.bson.Document 参数为key-value的格式 * 2. 创建文档集合List<Document> * 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document) * */ Document document = new Document("title", "MongoDB"). append("description", "database"). append("likes", 100). append("by", "Fly"); List<Document> documents = new ArrayList<Document>(); documents.add(document); collection.insertMany(documents); System.out.println("文档插入成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " +

    转载于:https://www.cnblogs.com/zhongqiong/p/7371930.html

    展开全文
  • mongodb

    千次阅读 2014-03-09 12:08:44
    MongoDB的内部构造《MongoDB The Definitive Guide》 MongoDB的官方文档基本是how to do的介绍,而关于how it worked却少之又少,本人也刚买了《MongoDB TheDefinitive Guide》的影印版,还没来得
  • MongoDB 是一个跨平台的,面向文档(文档相当于数据库中的一行)的数据库,是当前 NoSQL 数据库产品中最热门的一种。它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的产品。它...
  • Mongodb学习

    2021-08-01 20:07:21
    mongodb学习 参考文章:https://gitee.com/AoiX/studied/blob/master/documents/MongoDB.md 问题参考文章:https://www.cnblogs.com/angle6-liu/p/10791875.html 1. MongoDB 相关概念 1.1 业务场景 传统的关系型...
  • MongoDB总结

    千次阅读 2017-09-08 14:53:55
    MongoDB的官方文档基本是how to do的介绍,而关于how it worked却少之又少,本人也刚买了《MongoDB TheDefinitive Guide》的影印版,还没来得及看,本文原作者将其书中一些关于MongoDB内部现实方面的一些知识介绍...
  • MongoDB是一款非常知名的NoSQL文档数据库,而Spring则是Java领域著名的开源框架。除了构成Spring核心的IoC与AOP之外,Spring也有大量应用于各个不同领域的子框架,其中Spring Data就是专门针对数据处理的一
  • mongoose, 在异步环境中,为了工作而设计MongoDB对象建模 MongooseMongoose是一个用于在异步环境中工作的 MongoDB对象模型工具设计。 文档mongoosejs.com支持堆栈溢出Bug 报告Mongoose松弛通道帮助论坛MongoDB
  • 探索mongodb_探索MongoDB

    2020-07-03 18:36:25
    什么是MongoDB? 近年来,我们看到了对与传统关系模型不同的数据库管理系统的日益增长的兴趣。 它的核心是NoSQL的概念,该术语共同用于表示不使用结构化查询语言(SQL)与数据库进行交互的数据库软件。 NoSQL最...
  • MongoDB 是专为可扩展性,高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂的多数据中心架构。利用内存计算的优势,MongoDB 能够提供高性能的数据读写操作。 MongoDB 的本地复制和自动故障...
  • mongodb调研

    2015-07-30 18:21:09
    这是本人的一篇关于mongodb的调研报告,整理出来供大家交流,内容主要来源于mongodb官网的文档和其他网络资源。 转载请注明出处,谢谢。 Mongodb调研 1. 调研目的  现在公司缺乏一个...
  • MongoDB基础

    2018-03-15 09:08:00
    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像...
  • 关于MongoDB

    千次阅读 2015-12-14 20:11:46
    MongoDB的内部构造《MongoDB The Definitive Guide》 MongoDB的官方文档基本是how to do的介绍,而关于how it worked却少之又少,本人也刚买了《MongoDB TheDefinitive Guide》的影印版,还没来得及看,本文原...
  • MongoDB并非在实验室设计。我们通过自己建造大规模、高可用、健壮系统的经验构建了MongoDB。我们不是从零开始的,我们实际上是真的想发现问题并解决它。因此,我对MongoDB看法是,如果你采用Mysql,将关系模型改为...
  • MongoDB 学习笔记

    2020-10-22 09:54:26
    MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。 它支持的数据结构非常松散,是一种类似于 ...
  • mongoDB+javaSpring实现的选课系统demo,使用了MongoTemplate工具库,实现课程、教师信息、学生信息增删改查、实现简单的选课功能。
  • MongoDB 笔记

    2014-05-17 09:32:00
    Brian Dilley谈到了MongoDB的几个缺陷; 两个CRM库: morphia(针对MongoDB的Java库,是类型安全的) spring-data(Spring Data综合项目的MongoDB实现) “些ORM库使用了大量注解,出于很多原因,我并不倾...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,050
精华内容 2,420
关键字:

mongodb设计报告