`
裴小星
  • 浏览: 264994 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
8ccf5db2-0d60-335f-a337-3c30d2feabdb
Java NIO翻译
浏览量:27804
F3e939f0-dc16-3d6e-8c0b-3315c810fb91
PureJS开发过程详解
浏览量:74006
07a6d496-dc19-3c71-92cf-92edb5203cef
MongoDB Java ...
浏览量:62903
社区版块
存档分类
最新评论

Pure JS (4.1): 使用 MongoDB 进行数据存储和管理

阅读更多
Pure JS (4.1): 使用 MongoDB 进行数据存储和管理


  MongoDB 的一大特性就是 “JavaScript Friendly”,“Scheme Free” 的主张天生就是与 JavaScript 的开发理念相契合的。
  它允许我们通过 eval 进行数据的初始化,以及在查询中使用 JS 对象作为查询条件,并且查询结果也可以很容易地转为 JS 对象或数组。

  最近三篇文章将重点介绍如何在服务器端用 JS 与 MongoDB 进行交互;
  我将这些操作封装在 pure.db 中,可能封装得并不完善,但可以很容易地进行修改和扩展 。

  第一篇文章通过测试案例来了解 pure.db 的用法;
  第二篇文章说明在实际的 Web 应用中如何使用它;
  第三篇文章探讨 pure.db 的实现细节。

运行测试案例

  首先,我们需要到这里下载 MongoDB:http://www.mongodb.org/downloads

  通过命令行运行 mongod 和 mongo(默认情况下需要先在根目录创建文件夹 \data\db )。
  mongod 是一个接受命令的守护进程,而 mongo 是一个与 mongod 交互的命令行 shell 工具。

  然后下载附件,这是一个 eclipse 工程(就是我们之前一直使用的 PureJS 工程),添加到eclipse中,运行 test/purejs/test/DBTest.java。(鼠标右键 -> Run As -> JUnit Test 或 Alt + Shift + X, T)

  正常情况下,应该看到像这样的绿条:



引用
  如果出现 Error 或 Failure,在确认不是环境问题(mongod 正常运行中,Java 7 和 Junit 4 的配置没有问题)之后,请通过留言或站内信等方式通知我。


  我们可以看到 DBTest 类的结构是这样的:
package purejs.test;

import org.junit.*;
import purejs.core.*;

public class DBTest {
	@Before
	public void setUp() throws Exception {
		JSEngine.excuteFile("scripts/config.js");
		JSEngine.excuteFile("scripts/lib/pure.js");
		JSEngine.excuteFile("scripts/test/db/before.js");
	}

	@Test
	public void list() throws Exception {
		execute("list");
	}

	@Test
	public void listWithLimit() throws Exception {
		execute("listWithLimit");
	}

	@Test
	public void listWithEquals() throws Exception {
		execute("listWithEquals");
	}

	// 其他类似的测试方法 ...

	private void execute(String name) throws Exception {
		JSEngine.excuteFile("scripts/test/db/" + name + ".js");
		JSEngine.invoke("run");
	}
}

  也就是说每个测试方法实际上就是运行一个 js 文件,我们打开文件夹 scripts/test/db ,所有用于测试的 js 文件都在这里,总共有 25 个测试文件以及一个初始化脚本 before.js ,接下来我们将选择其中的重点进行说明。

通过 eval 进行数据的初始化

  数据初始化的脚本 before.js 调用 pure.db.eval(func) 进行数据的初始化,传入一个函数,函数中的代码将直接在 MongoDB 运行,可以在这里查看原生的 MongoDB js 的写法:
  http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart

  before.js 首先建立了一个测试框架:
function run() {
	setUp();
	execute();
	verify();
	tearDown();
}

  然后实现了 setUp 函数和 tearDown 函数,而 execute 函数和 verify 函数则分别在每个测试文件中实现。

  【setUp】

  在 setUp 函数中,首先调用 tearDown 函数进行数据的清理,然后通过 eval 进行数据初始化,初始化的步骤包括:
  1. 获取 DB 中名为 'users' 的 collection
  2. 为 collection 创建索引,索引字段为 name ,排序方式为升序
  3. 在 users 中存放一组测试数据

  具体实现如下:
function setUp() {
	tearDown();

	pure.db.eval(function(){
		var users = db.users;
		users.ensureIndex({ name: 1 });

		users.insert({ name: 'user1', desc: 'desc1' });
		users.insert({ name: 'user2', desc: 'desc2' });
		users.insert({ name: 'user3', desc: 'desc3' });
		users.insert({ name: 'xxxxx', desc: 'desc3', age: 20 });
	});
}

  虽然 eval 很酷,但根据官方文档说明,运行 eval 时将阻塞所有的其他操作。
  因此,最好只在数据初始化、数据迁移等特殊应用场景使用它。
  所有测试的前提就是 eval 可用,因此没有针对 eval 的测试。

  另外,因为建立了索引,所以后续的测试中通常不会对记录进行排序;但最近被更新的数据将被放在最后,顺序也就被打乱了。因此在实际应用中,每次获取数据后还是要进行排序的。

  向 users 中插入的前三个对象很有规律,而第四个对象是为了测试 dintict,exists 等函数的用法而特意增加的。

  【tearDown】

  tearDown 首先将 context 清空,通过 eval -> db.users.drop 删除 users。
  实现如下:
function tearDown() {
	context = {};

	pure.db.eval(function(){
		db.users.drop();
	});
}

  context 对象用于在 excute 函数和 verify 函数之间传递数据,所以每次执行测试前后都需要重新进行初始化。

测试案例介绍

  【list (find)】

  list 是我根据自己的习惯为 MongoDB 原生 JS 中的 find 方法起的一个别名,仍然使用find也是可以的。
  list.js 内容如下:
importPackage(org.junit);

function execute() {
	var users = pure.db.get('users');
	context.list = users.$list();
}

function verify() {	
	var list = context.list;

	Assert.assertEquals(4, list.length, 0);
	
	Assert.assertEquals('user1', list[0].name);
	Assert.assertEquals('desc1', list[0].desc);

	Assert.assertEquals('user3', list[2].name);
	Assert.assertEquals('desc3', list[2].desc);
}

  excute 函数中通过 pure.db.get 获取名为 'users' 的 collection,然后 list 方法获取 user 对象列表。
  list 函数名前带上 “$” 表示将结果转换为 JavaScript 数组,否则将继续保留 DBCursor 形式,以便进行排序等后续操作。

  verify 函数对结果的长度和特定对象进行检查。

  【listWithLimit】

  通过 list 方法获取 DBCursor 之后,我们还可以通过 limit 和 skip 方法限制返回对象的数量,这可以用于分页功能的实现:

importPackage(org.junit);

function execute() {
	var users = pure.db.get('users');
	context.list = users.list().limit(2).$skip(1);
}

function verify() {	
	var list = context.list;

	Assert.assertEquals(2, list.length, 0);
	
	Assert.assertEquals('user2', list[0].name);
	Assert.assertEquals('desc2', list[0].desc);

	Assert.assertEquals('user3', list[1].name);
	Assert.assertEquals('desc3', list[1].desc);
}

  limit(1) 表示返回值长度限制为 1 , skip(1) 表示跳过第一个对象。因此最终取到的列表就只有 'user2' 和 'user3' 了。

  【在 list 中增加比较条件】

  list 中增加 相等、大于、小于 等比较条件进行过滤。

  listWithEquals
context.list = users.$list({ name: 'user2' });

  listWithGreaterThen
context.list = users.$list({ name: { $gt: 'user2' } });

  listWithLesserThen
context.list = users.$list({ name: { $lt: 'user2' } });

  listWithMultipleEquals
context.list = users.$list({ name: 'user2', desc: 'desc2' });

  listWithMultipleCompare
context.list = users.$list({
	name: { $gt: 'user1', $lt: 'user3' }
});

  我们还可以用 $or 来表示不同条件之间是 “或” 的关系,如 listWithOr.js :
	context.list = users.$list({
		$or: [{ name: 'user1' }, { desc: 'desc2' } ]
	});

  【对结果进行排序和 distinct 及返回特定属性】

  使用 sort 方法可以对结果进行排序,参数为一个对象,对象的属性名称表示被排序的字段(这里的 name 或 desc),属性值为 1 (升序) 或 -1 (降序)。
  ditinct 方法可以去除重复,并且只返回特定字段的值。
  也可以在 list 的第二个参数中指定需要返回的特定属性。

  listWithOrder
context.list = users.list().$sort({ desc: 1 });

  listWithOrderDesc
context.list = users.list().$sort({ desc: -1 });

  listWithDistinct
context.list = users.distinct('desc');

  listSomeField
context.list = users.$list({}, { desc : 1 });

  【使用正则表达式及exists】

  我们还可以在过滤条件中使用正则表达式,从而替代传统 SQL 数据库中的 like 查询。
  也可以通过 $exists 检查包含某个特定属性的对象。

  listWithLike
	context.three = users.$list({ name: /user/ });
	context.one = users.$list({ name: /user1/ });

  listWithPrefix
	context.three = users.$list({ name: /^u/ });
	context.one = users.$list({ name: /^user1/ });

  listWithPostfix
	context.list = users.$list({ desc: /3$/ });

  listWithExists
	context.list = users.$list({ age: { $exists: true } });


  【count】

  count 函数可以对返回结果进行计数。

  count.js
context.count = users.count();

  listWithCount.js
context.count = users.list({ name: /user/ }).count();

  【get (findOne)】

  同样,get 是 findOne 的一个别名。
  get 的用法与 list 相似,但只返回符合条件的第一个对象。
context.user = users.get({ name: 'user1' });

  【insert】

  insert 用于增加对象
users.insert({ name: 'user4', desc: 'desc4' });

  【update】

  insert 用于更新对象,可以更新一条或多条,第一个参数表示被更新的记录符合的条件,第二个参数表示更新选项,第三个参数表示不存在的情况下是否插入记录,第四个对象表示是否更新多条。

  update.js
	var query = { name: 'user1' };
	users.update(query, { $set: { desc: 'new desc' } });

  updateMultiple.js
	var query = { name: /user/ };
	users.update(query, { $set: { desc: 'new desc' } }, false, true);

  关于 update 的测试并不全面,可以在这里找到更全面的说明:
  http://www.mongodb.org/display/DOCS/Updating

  【save】

  save 既可以用于插入,也可以用于更新。

  saveAsAdd.js
users.save({ name: 'user4', desc: 'desc4' });

  saveAsUpdate.js
	var user = users.get({ name: 'user1' });

	user.desc = 'new desc';
	users.save(user);

  【remove】

  remove 用于删除对象

  remove.js
users.remove({ name: 'user1' });
9
5
分享到:
评论

相关推荐

    Node.js 实践: 使用 MongoDB 存储数据代码

    Node.js 实践: 使用 MongoDB 存储数据 MongoDB命令行工具的使用 在项目中如何有效组织和使用Mongoose

    《Node应用程序构建:使用MongoDB和Backbone》 源码

    5. **Express框架**:在Node.js中,Express是最广泛使用的Web应用框架,简化了路由设置、中间件使用和视图渲染。学习如何使用Express构建RESTful API,是构建Node.js应用的基础。 6. **Backbone.js的Model和...

    Node应用程序构建——使用MongoDB和Backbone

    在本文中,我们将深入探讨如何使用Node.js构建应用程序,并结合MongoDB数据库以及Backbone.js作为前端框架,实现数据的高效管理和交互。Node.js是基于Chrome V8引擎的JavaScript运行环境,它让JavaScript能够运行在...

    非结构化数据库MongoDB的数据存储.pptx

    2、动态查询:MongoDB支持使用JavaScript表达式进行查询,这使得查询操作更加灵活和动态。 3、面向集合:MongoDB采用面向集合的方式进行数据存储,这使得数据的组织和检索更加方便。 4、可扩展性:MongoDB支持...

    MongoDB数据库应用.docx

    1. 学习曲线陡峭:MongoDB 的查询语法和数据模型不同于传统的关系型数据库,对于初学者来说可能存在一定的学习成本。 2. 不支持事务:MongoDB 不支持事务操作,对于需要事务支持的应用场景不太适合。 Windows 下 ...

    MongoDB入门到云上开发视频.zip

    课时2:MongoDB数据数据查询与分析.mp4 课时3:MongoDB数据库核心知识.mp4 课时4:MongoDB数据库管理备份.mp4 课时5:MongoDB开发实战:开发博客应用.mp4 课时6:MongoDB数据库性能分析与调优.mp4 课时7:MongoDB...

    java中mongodb使用环境详细配置

    Java 中 MongoDB 使用环境详细配置 Java 中 MongoDB 使用环境详细配置是指在 Windows 平台(WinXP)上安装、运行...这些知识点对于 Java 开发者来说非常重要,可以帮助他们更好地使用 MongoDB 进行数据的存储和管理。

    geoserver发布mongodb矢量数据地图服务.docx

    Geoserver可以连接MongoDB数据库,实现矢量数据的存储和发布。Geoserver提供了强大的MongoDB插件,可以实现MongoDB矢量数据的读取和写入。 发布步骤: 1. 创建工作区 首先,需要创建一个工作区,用于存储矢量数据...

    mongodb-测试数据

    MongoDB使用JSON格式的文档(BSON)作为其数据存储单位,这种格式易于理解和处理,尤其适合处理结构松散或半结构化数据。数据库由集合组成,集合又由文档构成。它支持丰富的查询语法,可以进行复杂的聚合操作,同时...

    深入云计算:MongoDB管理与开发实战详解 源代码

    8. 应用集成:了解如何在各种编程语言(如Java、Python、Node.js等)中使用MongoDB驱动程序,实现高效的数据交互。 9. 实战项目:通过书中提供的源代码,实践将MongoDB应用于实际项目,如日志分析、社交网络、电子...

    windows下mongodb安装与使用整理

    本文详细介绍了在 Windows 系统下安装和配置 MongoDB 的步骤,以及如何将 MongoDB 作为 Windows 服务进行管理。通过这些步骤,用户可以轻松地在本地环境中搭建并使用 MongoDB 数据库。此外,还提供了基本的 MongoDB ...

    MongoDB应用设计模式:MongoDB Applied Design Patterns

    - **分片策略**:如何根据数据量和访问模式选择合适的分片键,确保负载均衡和数据分布均匀。 - **自动分片**:MongoDB支持自动分片,可以随着数据增长动态调整分片配置。 - **副本集**:为了实现高可用性,...

    Pure JS (4.3): pure.db.js 的实现(基于 MongoDB Rhino Driver)

    《纯JavaScript实现:pure.db.js基于MongoDB Rhino Driver详解》 在JavaScript的世界里,数据库操作通常依赖于服务器端的语言支持,如PHP、Python或Node.js等。然而,有一种另辟蹊径的方式,即通过Rhino JavaScript...

    MongoDB实战:MongoDB in Action

    10. **应用程序集成**:MongoDB支持多种编程语言的驱动程序,如Python、Java、Node.js等,书中会介绍如何在各种开发环境中集成和使用MongoDB。 11. **运维与监控**:书中还会讲解如何监控MongoDB实例的健康状况,...

    MongoDB数据库管理工具

    通过使用MongoVUE这样的管理工具,开发者和DBA能够更高效地管理MongoDB数据库,提高工作效率,同时也能更好地理解和调试应用程序与数据库之间的交互。对于初学者,MongoVUE是一个很好的学习平台,可以直观地了解...

    TDC2015-Geolocation:使用MongoDB进行地理位置和内容之间的关系。 该工具的API强大且简单,可处理Geolocated数据

    定位针头:使用MongoDB获取地理定位数据使用MongoDB进行地理位置和内容之间的关系。 该工具的API健壮且简单,允许处理Geolocated数据。 向用户推荐内容是Superplayer的重点之一。 从年初开始,我们就使用MongoDB创建...

    demo-mongodb.zip

    1. **文档数据库**:MongoDB存储数据以JSON(JavaScript Object Notation)格式的文档形式,这使得数据结构灵活,可以方便地存储复杂的数据类型如数组和嵌套对象。 2. **集合和数据库**:在MongoDB中,数据存储在...

Global site tag (gtag.js) - Google Analytics