mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。
但是mongodb提供了许多原子操作,比如文档的保存,修改,删除等,都是原子操作。
所谓原子操作就是要么这个文档保存到Mongodb,要么没有保存到Mongodb,不会出现查询到的文档没有保存完整的情况。
考虑下面的例子,图书馆的书籍及结账信息。
实例说明了在一个相同的文档中如何确保嵌入字段关联原子操作(update:更新)的字段是同步的。
book = { _id: 123456789, title: "MongoDB: The Definitive Guide", author: [ "Kristina Chodorow", "Mike Dirolf" ], published_date: ISODate("2010-09-24"), pages: 216, language: "English", publisher_id: "oreilly", available: 3, checkout: [ { by: "joe", date: ISODate("2012-10-15") } ] }
你可以使用 db.collection.findAndModify() 方法来判断书籍是否可结算并更新新的结算信息。
在同一个文档中嵌入的 available 和 checkout 字段来确保这些字段是同步更新的:
db.books.findAndModify ( { query: { _id: 123456789, available: { $gt: 0 } }, update: { $inc: { available: -1 }, $push: { checkout: { by: "abc", date: new Date() } } } } )
用来指定一个键
MongoDB 查询分析可以确保我们所建立的索引是否有效,是查询语句性能分析的重要工具。
MongoDB 查询分析常用函数有:explain() 和 hint()。
explain 操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。
接下来我们在 users 集合中创建 gender 和 user_name 的索引:
>db.users.ensureIndex({gender:1,user_name:1})
现在在查询语句中使用 explain :
>db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
以上的 explain() 查询返回如下结果:
{ "cursor" : "BtreeCursor gender_1_user_name_1", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 0, "nscanned" : 1, "nscannedObjectsAllPlans" : 0, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : true, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "gender" : [ [ "M", "M" ] ], "user_name" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] } }
现在,我们看看这个结果集的字段:
官方的MongoDB的文档中说明,覆盖查询是以下的查询:
由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配查询条件和返回使用相同索引的查询结果。
因为索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多。
为了测试覆盖索引查询,使用以下 users 集合:
{ "_id": ObjectId("53402597d852426020000002"), "contact": "987654321", "dob": "01-01-1991", "gender": "M", "name": "Tom Benzamin", "user_name": "tombenzamin" }
我们在 users 集合中创建联合索引,字段为 gender 和 user_name :
>db.users.ensureIndex({gender:1,user_name:1})
现在,该索引会覆盖以下查询:
>db.users.find({gender:"M"},{user_name:1,_id:0})
也就是说,对于上述查询,MongoDB的不会去数据库文件中查找。相反,它会从索引中提取数据,这是非常快速的数据查询。
由于我们的索引中不包括 _id 字段,_id在查询中会默认返回,我们可以在MongoDB的查询结果集中排除它。
下面的实例没有排除_id,查询就不会被覆盖:
>db.users.find({gender:"M"},{user_name:1})
最后,如果是以下的查询,不能使用覆盖索引查询:
在上一章节MongoDB关系中我们提到了MongoDB的引用来规范数据结构文档。
MongoDB 引用有两种:
考虑这样的一个场景,我们在不同的集合中 (address_home, address_office, address_mailing, 等)存储不同的地址(住址,办公室地址,邮件地址等)。
这样,我们在调用不同地址时,也需要指定集合,一个文档从多个集合引用文档,我们应该使用 DBRefs。
DBRef的形式:
{ $ref : , $id : , $db : }
三个字段表示的意义为:
以下实例中用户数据文档使用了 DBRef, 字段 address:
{ "_id":ObjectId("53402597d852426020000002"), "address": { "$ref": "address_home", "$id": ObjectId("534009e4d852427820000002"), "$db": "istudy"}, "contact": "987654321", "dob": "01-01-1991", "name": "Tom Benzamin" }
address DBRef 字段指定了引用的地址文档是在 runoob 数据库下的 address_home 集合,id 为 534009e4d852427820000002。
以下代码中,我们通过指定 $ref 参数(address_home 集合)来查找集合中指定id的用户地址信息:
>var user = db.users.findOne({"name":"Tom Benzamin"}) >var dbRef = user.address >db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
以上实例返回了 address_home 集合中的地址数据:
{ "_id" : ObjectId("534009e4d852427820000002"), "building" : "22 A, Indiana Apt",
MongoDB 的关系表示多个文档之间在逻辑上的相互联系。
文档间可以通过嵌入和引用来建立联系。
MongoDB 中的关系可以是:
接下来我们来考虑下用户与用户地址的关系。
一个用户可以有多个地址,所以是一对多的关系。
以下是 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" }
使用嵌入式方法,我们可以把用户地址嵌入到用户的文档中:
{ "_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
MongoDB是一种文档导向数据库管理系统,由C++撰写而成。
本章节我们将为大家介绍如何使用 Node.js 来连接 MongoDB,并对数据库进行操作。
如果你还没有 MongoDB 的基本知识,可以参考我们的教程:MongoDB 教程。
本教程使用了淘宝定制的 cnpm 命令进行安装:
$ cnpm install mongodb
接下来我们来实现增删改查功能。
要在 MongoDB 中创建一个数据库,首先我们需要创建一个 MongoClient 对象,然后配置好指定的 URL 和 端口号。
如果数据库不存在,MongoDB 将创建数据库并建立连接。
我们可以使用 createCollection() 方法来创建集合:
与 MySQL 不同的是 MongoDB 会自动创建数据库和集合,所以使用前我们不需要手动去创建。
以下实例我
在php中使用mongodb你必须使用 mongodb 的 php驱动。
MongoDB PHP在各平台上的安装及驱动包下载请查看:PHP安装MongoDB扩展驱动
如果你使用的是 PHP7,请参阅:PHP7 MongoDB 安装与使用。
为了确保正确连接,你需要指定数据库名,如果数据库在mongoDB中不存在,mongoDB会自动创建
代码片段如下:
<?php $m = new MongoClient(); // 连接默认主机和端口为:mongodb://localhost:27017 $db = $m->test; // 获取名称为 "test" 的数据库 ?>
创建集合的代码片段如下:
<?php $m = new MongoClient(); // 连接 $db = $m->test; // 获取名称为 "test" 的数据库 $collection = $db->createCollection("runoob"); echo "集合创建成功"; ?>
执行以上程序,输出结果如下:
集合创建成功
在mongoDB中使用 insert() 方法插入文档:
插入文档代码片段如下:
<?php $m = new MongoClient(); // 连接到mongodb $db = $m->test; // 选择一个数据库 $collection = $db->runoob; // 选择集合 $document = array( "title" => "MongoDB", "description" => "database", "likes" => 100, "url" => "http://www.istudy.wang/blog/tag/admin/MongoDB", "by", "iStudy" ); $collection->insert($document); echo "数据插入成功"; ?>
执行以上程序,输出结果如下:
数据插入成功
然后我们在 mongo 客户端使用 db.runoob.find().pretty(); 命令查看数据:
使用find() 方法来读取集合中的文档。
读取使用文档的代码片段如下:
<?php $m = new
本教程将向大家介绍如何在Linux、window、Mac平台上安装MongoDB扩展。
你可以在 Linux 中执行以下命令来安装 MongoDB 的 PHP 扩展驱动
$ sudo pecl install mongodb
使用php的pecl安装命令必须保证网络连接可用以及root权限。
如果你想通过源码来编译扩展驱动。你必须手动编译源码包,这样做的好是最新修正的 bug 包含在源码包中。
你可以在 PHP 官网上下载 MongoDB PHP 驱动包,下载地址:http://pecl.php.net/package/mongodb。
完整安装命令如下:
$ wget http://pecl.php.net/get/mongodb-1.5.2.tgz $ cd /mongodb-1.5.2 $ phpize $ ./configure $ make && make install
如果你的 php 是自己编译的,则安装方法如下(假设是编译在 /usr/local/php目录中):
$ wget http://pecl.php.net/get/mongodb-1.5.2.tgz $ cd /mongodb-1.5.2 $ /usr/local/php/bin/phpize $ ./configure --with-php-config=/usr/local/php/bin/php-config $ make && make install
安装成功后,会有类似以下安装目录信息输出:
... Installing shared extensions: /usr/lib/php/extensions/debug-non-zts-20151012/
执行以上命令后,你需要修改php.ini文件,在 php.ini 文件中添加mongo配置,配置如下:
extension_dir=/usr/lib/php/extensions/debug-non-zts-20151012/ extension=mongodb.so
注意:你需要指明 extension_dir 配置项的路径。
可以通过以下命令查看目录地址:
$ php -i | grep extension_dir extension_dir =>
环境配置
在 Java 程序中如果要使用 MongoDB,你需要确保已经安装了 Java 环境及 MongoDB JDBC 驱动。
本章节实例时候 Mongo 3.x 以上版本。
你可以参考本站的Java教程来安装Java程序。现在让我们来检测你是否安装了 MongoDB JDBC 驱动。
首先你必须下载mongo jar包,下载地址:https://mongodb.github.io/mongo-java-driver/, 请确保下载最新版本。
连接数据库,你需要指定数据库名称,如果指定的数据库不存在,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() ); } } }
现在
在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能。这样在大流量得情况下可以很好的应对并保证MongoDB正常运作。
MongoDB中提供了mongostat 和 mongotop 两个命令来监控MongoDB的运行情况。
mongostat是mongodb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。
启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat命令,如下所示:
D:\set up\mongodb\bin>mongostat
以上命令输出结果如下:
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 - 锁,这将产生以下输出:
输出结果字段说明:
包含数据库命名空间,后者结合了数据库名称和集合。
db:
包含数据库的名称。名为 . 的数据库针对全局锁定,而非特定数据库。
total:
mongod花费的时间工作在这个命名空间提供总额。
read:
提供了大量的时间,这mongod花费在执行读操作,在此命名空间。
write:
提供这个命名空间进行写操作,这mon