`

MongoDB入门

阅读更多

 

MongoDB入门

 

连接数据库

 

在这里我们使用MongoDB提供的JavaScript shell进行数据库操作,当然也可以通过不同的驱动利用其他编程语言实现同样的功能,不过shell在管理数据库的方面还是很方便的。

 

启动JavaScript shell的方法很简单,命令如下:

 

C:\mongodb\bin\mongo

 

在默认情况下,shell连接到本地test数据库,可以看到如下信息:

 

C:\mongodb\bin>mongo

MongoDB shell version: 2.0.2

connecting to: test

 

connecting to”的后面是要连接的数据库的名字,如果想换成其他的数据库,可以用如下命令:

 

> use mydb

switched to dbmydb

 

注意:切换数据库后,如果切换的数据库不存在,系统并不会马上创建这个数据库,而是在对它进行第一次插入操作时才创建。这意味着当你使用“show dbs”命令查看现有数据库时,并不能看到切换的数据库。

 

动态模式(无模式)

 

MongoDB包含数据库(database)、集合(collection),以及和传统关系数据库很相似的索引结构(index)。对于数据库和集合这些对象(object),系统会隐式地进行创建,然而一旦创建它们就被记录到了系统目录中(db.systems.collectionsdb.system.indexes)。

 

集合由文档(document)组成,文档中包含域(field),也就是传统关系数据库中的字段。但与关系数据库不同,MongoDB不会对域进行预定义,也没有给文档定义模式,这就意味着文档中不同域和它们的值是可以变化的。因此,MongoDB并没有“alter table”操作来增加或者减少域的个数。在实际应用中,一个文档中通常包含相同类型的结构,但这并不是必须的。这种弹性使得模式变动或者增加变得非常容易,几乎不用写任何脚本程序就可实现“alter table”操作。另外,动态模式机制便于对基于MongoDB数据库的软件进行重复性开发,大大减少了由于模式变化所带来的工作量。

 

向集合中插入数据

 

首先创建一个名为test的集合,再向test中插入数据。我们创建两个对象jt,然后将它们保存到集合things中。

 

在下面的例子中,“>”表示shell命令提示符:

 

>j={name:"mongo"}

{ "name" : "mongo" }

> t={x:3}

{ "x" : 3 }

>db.things.save(j)

>db.things.save(t)

>db.things.find()

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

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

 

注意:

—我们并没有预定义集合,数据库是在进行第一次插入操作时自动创建集合的。

—我们存储的文档包含不同的域,在这个例子中,文档中没有相同的数据元素。但在实际
     
应用中,往往把相同结构的数据存储在一个集合中。

—一旦被存储到数据库中,如果没有事先定义,对象就会被自动分配一个ObjectId,并且
     
存储到field_id域中。当你运行上面的例子时,会有不同的ObjectId

 

向集合中增加更多的记录,下面的代码利用了循环结构:

 

> for (var i=1; i<=20; i++) db.things.save({x:4,j:i})

>db.things.find()

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

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6034"), "x" : 4, "j" : 18 }

has more

 

值得注意的是,上面例子中没有显示出全部的文档,shell默认显示的数目是20。如果想查看其余的文档,可以使用it命令:

 

{ "_id" : ObjectId("4f36234964480e0bcb6d6034"), "x" : 4, "j" : 18 }

has more

>it

{ "_id" : ObjectId("4f36234964480e0bcb6d6035"), "x" : 4, "j" : 19 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

 

严格来讲,find()返回的是指针对象。但是在上面的例子中,我们并没有把指针对象赋予任何变量。所以,shell自动对指针进行迭代,直到给出初始的结果集,我们可以通过it命令显示出其余的信息,但是也可以直接对find()返回的指针进行操作,11.3.3.4节中将对其进行介绍。

 

查询数据

 

在讨论数据查询之前,先了解一下如何操作查询结果,即指针对象。我们将使用简单的find()方法,返回集合中全部的文档,之后再讨论如何写出特定的查询语句。

 

为了了解使用mongo shell时集合中的全部元素,我们需要明确地使用find()方法返回的指针。利用while循环对find()返回的指针进行迭代,实现和前面例子相同的查询结果:

 

>var cursor=db.things.find()

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

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

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

 

上面的例子显示了指针迭代器,hasNext()方法判断是否还能返回文档,next()方法返回下一个文档。我们也使用了内置的printjson()方法使文档以JSON形式展现。

 

当在JavaScript shell下工作时,我们也可以利用JavaScript语言的特征,比如使用forEach输出指针对象。下面的代码输出与上面相同的查询结果,但是在代码中使用forEach而不是while循环:

 

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

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

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

 

在使用forEach()方法的时候,必须为指针指向的每一个文档定义函数(这里用了内置方法printjson())。

 

mongo shell中,可以像对数组一样操作指针:

 

>var cursor=db.things.find()

>printjson(cursor[4])

{ "_id" : ObjectId("4f36234964480e0bcb6d6025"), "x" : 4, "j" : 3 }

 

当用这种方式使用指针时,指针指示的值都能同时加载到内存中,这一点不利于返回较大的查询结果,因为有可能发生内存溢出。对于结果较大的查询,应该用迭代方式输出指针值。

 

另外,你可以将指针转变为真正的数组进行处理:

 

>arr[5]

{ "_id" : ObjectId("4f36234964480e0bcb6d6026"), "x" : 4, "j" : 4 }

 

注意,这些数组特性都仅适用于shell模式,但对于其他语言环境并不适合。MongoDB指针并不是快照,当在集合上进行操作时,如果有其他人在集合里第一次或者最后一次调用next(),那么你的指针可能不能成功返回结果,所以要明确锁定你要查询的指针。

 

条件查询

 

我们已经知道如何操作查询返回的指针,现在我们要针对特定条件实现对查询结果的筛选。一般来说,实现条件查询就需要建立“查询文档”,即指明键需要匹配的模式和值的文档。对于这一点用例子证明要比用文字解释清楚得多。在下面的例子中,我们将给出SQL查询,并且说明如何借助mongo shell使得MongoDB能实现相同的查询(参见表11-4与表11-5)。这种条件查询是MongoDB的基本功能,所以你也可以用其他程序驱动或者语言实现条件查询。

 

11-4  MongoDB条件查询(name="mongo"

 

SELECT * FROM things WHERE name="mongo"

>db.things.find({name:"mongo"}).forEach(printjson)

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

 

11-5  MongoDB条件查询(x=4

 

SELECT * FROM things WHERE x=4

>db.things.find({x:4}).forEach(printjson)

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6024"), "x" : 4, "j" : 2 }

 

续表 

 

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

 

查询表达式本身是一个文档,一个查询文档{a:Ab:B…}意思是“where a==A and b==B and …”。如果想了解更多条件查询有关的信息,可以到MongoDB官网上查看MongoDB开发者手册,网址如下:

 

http://www.mongodb.org/display/DOCS/Manual

 

MongoDB也允许返回“部分文档”,也就是结果中只包含数据库文档的一些子元素,类似于关系数据库中针对某些列的查询。为了实现这个查询,可以在find()方法中增加第二个参数,表示返回某些特定元素。为了便于说明,下面我们还是实现find({x:4})的查询,只不过增加了额外的参数使得结果中只包含j元素:

 

11-6  MongoDB条件查询(返回特定元素j

 

SELECT j FROM things WHERE x=4

>db.things.find({x:4},{j:true}).forEach(printjson)

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "j" : 20 }

 

注意:_id”字段总是会返回在结果中的。

 

 

 

作者简介

 

陆嘉恒,中国人民大学教授,博士生导师。2006年毕业于新加坡国立大学计算机科学系,获博士学位;2006-2008年在美国加利福尼亚大学尔湾分校(University of California, Irvine)进行博士后研究;2008年加入中国人民大学,2012年破格晋升为教授。主要研究领域包括数据库技术和云计算技术。先后在SIGMODVLDBICDEWWW等国际重要会议和期刊上发表数据库方向的论文40多篇,主编多本云计算和大数据的教材和著作。

 

本文节选自《大数据挑战与NoSQL数据库技术》一书。陆嘉恒编著,由电子工业出版社出版。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics