`

mongodb实践 1

阅读更多

项目上用过Memcached,最近学习了一下mongodb。把学习过程总结一下:

注册iteye三年了,这是头一回发文章,实在惭愧:(

 

 

mongodb是一个开源的文档型数据库,是一种典型的NoSql数据库。mongodb官网上介绍mongodb的用例包括:实时分析、日志处理、电子商务、文档归档等。

一下内容是本人学习mongodb时的笔记,主要是shell操作的部分。

 

#mongodb安装

 

*下载mongodb的安装文件mongodb-win32-x86_64-1.6.5.zip,将其解压,为了方便将解压后的文件名命名为mongodb,如:F:/mongodb。

*创建mongodb的数据库存储文件夹,如F:/data/db。

*进入cmd,cd到~/bin目录,输入mongod -dbpath=F:/data/db(经测试"/"和"\"均能都可以使用--注:window7环境,"~"代表安装目录)启动mongodb数据库,可按Ctrl+C关闭数据库。

*再打开cmd窗口,cd到~/bin,输入mongo命令,默认连接到test数据库,输入db命令可查看所有数据库。

 

此时F:/data/db目录下空空如也,因为mongodb并没有正在创建test数据库,当有数据插入操作是mongodb才会真正创建数据库,同理使用use命令切换到某个本来不存在数据库下并不代表数据库

被真正创建了。

mongodb的官网上这么说@

给有其他数据库经验的开发者的提示

在下面的例子中你可能会注意到,我们没有创建数据库和聚集。MongoDB并不用那么做。一旦你插入数据,MongoDB会建立对应的聚集和数据库。要是查询了不存在的聚集,Mongo就将其视为空的聚集。

使用 use 命令来切换数据库不会立即创建数据库 - 数据库会在首次插入数据时延迟创建。这意味着如果首次 use 一个数据库,该数据库不会在 show dbs 命令的列表里显示出来,直到插入数据。

 

#连接到数据库,通过shell来操作数据库

 

#连接数据库,获取帮助信息

 

*~/bin/mongo.exe文件是shell命令的执行文件(注:此shell非彼shell,不要与Unix下的shell混淆),这里的shell实际上就是js。打开一个cmd窗口,cd到~/bin,输入mongo -h命令,得到如下帮助信息@

 

	MongoDB shell version: 1.6.5
	usage: mongo [options] [db address] [file names (ending in .js)]
	db address can be:
	  foo                   foo database on local machine
	  192.169.0.5/foo       foo database on 192.168.0.5 machine
	  192.169.0.5:9999/foo  foo database on 192.168.0.5 machine on port 9999
	options:
	  --shell               run the shell after executing files
	  --nodb                don't connect to mongod on startup - no 'db address' 
				arg expected
	  --quiet               be less chatty
	  --port arg            port to connect to
	  --host arg            server to connect to
	  --eval arg            evaluate javascript
	  -u [ --username ] arg username for authentication
	  -p [ --password ] arg password for authentication
	  -h [ --help ]         show this usage information
	  --version             show version information
	  --ipv6                enable IPv6 support (disabled by default)
 

 

 

file names: a list of files to run. files have to end in .js and will exit after unless --shell is specified

#向数据库插入数据

 

*在shell中输入命令@

 

> r = {name:"mongo"};

		{ "name" : "mongo" }
		> db.things.save(r);
		> r = {description : "mongodb is a no sql db"}
		{ "description" : "mongodb is a no sql db" }
		> db.things.save(r);
		> db.things.find();
		{ "_id" : ObjectId("4ee84d530c16000000006ec4"), "name" : "mongo" }
		{ "_id" : ObjectId("4ee84dee0c16000000006ec5"), "description" : "mongodb is a no sql db" }
 

 

mongodb是自由模式,或者说是动态模式的,mongodb的官网上如是说@

 

写道

A MongoDB collection is a collection of BSON documents. These documents usually have the same structure, but this is not a requirement since MongoDB is a schema-free (or more accurately, "dynamic schema") database. You may store a heterogeneous set of documents within a collection, as you do not need predefine the collection's "columns" or fields.
A collection is created when the first document is inserted.
Collection names should begin with letters or an underscore and may include numbers; $ is reserved. Collections can be organized in namespaces; these are named groups of collections defined using a dot notation. For example, you could define collections blog.posts and blog.authors, both reside under "blog". Note that this is simply an organizational mechanism for the user -- the collection namespace is flat from the database's perspective.
The maximum size of a collection name is 128 characters (including the name of the db and indexes). It is probably best to keep it under 80/90 chars.
 

注意几点:

我们并没有预先定义聚集。数据库会在第一次插入操作时自动创建集。

我们存储的文档可以拥有任意不同的“结构”。事实上在本例中,文档之间根本没有共同的数据元素。在实际应用中文档通常都以相同的结构保存在聚集里面。这种灵活意味着迁移或者扩展都非常容易。几乎不需要写脚本来执行诸如“alter table”之类的操作。

一旦被插入数据库,对象就被分配一个 [object ID](要是还没有的话)存储在 _id 域中

你运行上面的例子时,你的ObjectID的值会有所不同。

 

解释一下:命令中的db可以理解为我们使用的数据库"mydb",things可以理解为mydb中的一张数据库,而r可以理解为一行记录。

 

*使用for循环插入数据@

for (var i = 1; i <= 20; i++) db.things.save({i : i, i2 : i*i});

这条命令向数据库插入了20条数据,数据的第一个元素为i,第二个元素为i的平方。

#查询数据

 

*使用游标查询数据库,可以@

 

> var cursor = db.things.find();

> while (cursor.hasNext()) printjson(cursor.next());
 

 

打印信息省略。。。

第一条语句获得一个游标,第二条语句遍历游标,将文档对象转换为json格式打印出来。

也可以@

> db.things.find().forEach(printjson);

 

打印信息省略。。。

 

或者还可以将游标当作数组,但是这是有风险的,当数据量很大的时候需要考虑内存的容量,否则后果^_^!!!@

> var cursor = db.things.find();

		> printjson(cursor[4]);
		{ "_id" : ObjectId("4ee8510a0c16000000006ec8"), "i" : 3, "i2" : 9 }
		或者干脆转换为数组@
		> var arr = db.things.find().toArray();
		> arr[4]
		{ "_id" : ObjectId("4ee8510a0c16000000006ec8"), "i" : 3, "i2" : 9 }
 

#条件查询

 

*查询name为mongo的记录,可以这样@

> db.things.find({name:"mongo"}).forEach(function(x) {print(tojson(x));});

		{ "_id" : ObjectId("4ee84d530c16000000006ec4"), "name" : "mongo" }
 

这条语句返回所有name为mongo的记录。

*查询某个具体的域可以这么写@

> db.things.find({i:4},{i2:true}).forEach(function(x) {print(tojson(x));});

		{ "_id" : ObjectId("4ee8510a0c16000000006ec9"), "i2" : 16 }
		{ "_id" : ObjectId("4ee8514d0c16000000006edd"), "i2" : 16 }
 

这条语句返回所有i为4的数据的i2域,类似于sql中的“SELECT j FROM things WHERE x=4”,同理上面一条语句翻译成sql应当是“SELECT * FROM things WHERE name = 'mongo'”。

mongodb官网如是说@

查询表达式本身就是一个文档对象,如果是一个类似于{a:A, b:B, ...}的文档查询对象,则表示”where a==A and b==B and ...”。

那么多个条件的查询语句就可以这么写@

> db.things.find({i:4,i2:16}).forEach(function(x) {print(tojson(x));});

		{ "_id" : ObjectId("4ee8510a0c16000000006ec9"), "i" : 4, "i2" : 16 }
 

*查询一条记录@

> db.things.findOne({name:"mongo"});

		{ "_id" : ObjectId("4ee84d530c16000000006ec4"), "name" : "mongo" }
 

这条语句不返回游标,它返回数据库中满足条件的第一条记录。

 

*查询前n条记录@

> db.things.find().limit(3);

		{ "_id" : ObjectId("4ee84d530c16000000006ec4"), "name" : "mongo" }
		{ "_id" : ObjectId("4ee84dee0c16000000006ec5"), "description" : "mongodb is a no sql db" }
		{ "_id" : ObjectId("4ee8510a0c16000000006ec6"), "i" : 1, "i2" : 1 }
 

 

那么要达到mysql中limit m,n的效果要怎么办呢?不着急,先查看一下帮助信息,&这是个好习惯:),输入命令@

> db.things.find().help();

		find() modifiers
			.sort( {...} )
			.limit( n )
			.skip( n )
			.count() - total # of objects matching query, ignores skip,limit
			.size() - total # of objects cursor would return, honors skip,limit
			.explain([verbose])
			.hint(...)
			.showDiskLoc() - adds a $diskLoc field to each returned object

		Cursor methods
			.forEach( func )
			.print() - output to console in full pretty format
			.map( func )
			.hasNext()
			.next()
 

我们可以组合一下命令来达到limit m,n的效果。不管行不行,先运行如下命令@

> db.things.find().skip(10).limit(3);

		{ "_id" : ObjectId("4ee8510a0c16000000006ece"), "i" : 9, "i2" : 81 }
		{ "_id" : ObjectId("4ee8510a0c16000000006ecf"), "i" : 10, "i2" : 100 }
		{ "_id" : ObjectId("4ee8510a0c16000000006ed0"), "i" : 11, "i2" : 121 }
 

很神奇啊,mongo支持串联的操作!

 

*查询和排序还可以这样操作@

> db.things.find( { $query : { i : 3, i2 : 9 }, $orderby : { i2 : 1 } } );

		{ "_id" : ObjectId("4ee8510a0c16000000006ec8"), "i" : 3, "i2" : 9 }
		{ "_id" : ObjectId("4ee8514d0c16000000006edc"), "i" : 3, "i2" : 9, "i3" : 27 }
 

*在mongodb中null值有点特别@

		> db.things.find({i:100,i3:null});{ "_id" : ObjectId("4ee96a64bd3e000000003380"), "i" : 100, "i2" : 10000, "i3" : null }
		> db.things.find({i3:{$exists :false }});
		{ "_id" : ObjectId("4ee84d530c16000000006ec4"), "name" : "mongo" }
		{ "_id" : ObjectId("4ee84dee0c16000000006ec5"), "description" : "mongodb is a no sql db" }
		{ "_id" : ObjectId("4ee8510a0c16000000006ec6"), "i" : 1, "i2" : 1 }
		{ "_id" : ObjectId("4ee8510a0c16000000006ec7"), "i" : 2, "i2" : 4 }
		{ "_id" : ObjectId("4ee8510a0c16000000006ec8"), "i" : 3, "i2" : 9 }
		...
 

查询的方式也有很多@

$all

		$exists
		$mod
		$ne
		$in
		$nin
		$nor
		$or
		$and
		$size
		$type
		$regex
		$where
 

其中$regex支持类似传统关系型数据库中的 LIKE '%ABC'(以ABC结尾的字符) 这样的方式。例如@

> db.customers.find( { name : /j*i/ } );

		{ "_id" : ObjectId("4ee9924c8b12000000004f85"), "name" : "joy white", "age" : 23 }
 

mongodb官方说@

mongo是一个完备的JavaScript shell,所以任何JavaScript方法,语法或类都可以在shell中使用。所以你完全可以当自己在写javascript脚本。

 

从来都是看别人的文章,原来写文章其实很累啊 !

 

 

分享到:
评论
1 楼 diyunpeng 2012-10-16  
学习了。真的不错。

相关推荐

Global site tag (gtag.js) - Google Analytics