日期:2012/02/06 来源:GBin1.com
大家都听说过nosql解决方案吧?现在是web开发中很流行的技术。 是不是也有听说过MongoDB? 你是不是准备好了来学习一下web开发中最酷的技术之一MongoDB?
上一篇文章我们介绍了MongoDB基础知识,包括安装,创建基本的Database,及其执行简单的查询操作,今天我们接着介绍一些高级特性,包括如何使用selecor与数据库互动。Selector赋予了我们更细颗粒的控制和查询的能力。
如果你想真正的使用MongoDB开发一个应用,你需要学习更多。
今天我们将扩展介绍俩个关键的MongoDB特性:
- 高级查询
- Mapreduce
高级查询
上一篇文章我们介绍了基本的查询并且介绍了Selector(选择器)。现在我们需要学习更复杂的查询,基于上一次的介绍我们介绍俩个关键的使用:
- 条件运算符
- 正则表达式
条件运算符
正如它的名字,条件运算符用来收集查询并且匹配查询内容。这里有很多,今天我们主要介绍9个关键的运算符,如下:
- $lt - 必须小于
- $gt - 必须大于
- $lte - 必须小于或者等于
- $gte - 必须大于或者等于
- $in - 必须存在于一组条件中
- $nin - 必须不存在于一组条件中
- $not - 必须不等于一个条件
如果你使用过类似mysql的数据库,你基本也了解以上关键字作用。为了更好的演示,我们这里需要修改一些数据库内容。我们将添加一个age的属性。运行如下代码:
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a27b")}, {"$set" : {"age" : 18 }});
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a27c")}, {"$set" : {"age" : 45 }});
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a27d")}, {"$set" : {"age" : 65 }});
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a27e")}, {"$set" : {"age" : 43 }});
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a27f")}, {"$set" : {"age" : 22 }});
db.gbin1.update({"_id" : ObjectId("4f2f473bc9031ac66270a280")}, {"$set" : {"age" : 45 }});
db.gbin1.update({"_id" : ObjectId("4f2f473cc9031ac66270a281")}, {"$set" : {"age" : 33 }});
注意:如果你的数据库中的_id和我这里的演示不一样,请针对你自己的_id值更新数据
如果你运行以上命令后,你查询内容将得到以下输出:
db.gbin1.find();
{ "_id" : ObjectId("4f2f473bc9031ac66270a27b"), "age" : 18, "dob" : "21/04/1978", "first" : "matthew", "gender" : "m", "hair_colour" : "brown", "last" : "setter", "nationality" : "australian", "occupation" : "developer" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27c"), "age" : 45, "dob" : "26/03/1940", "first" : "james", "gender" : "m", "hair_colour" : "brown", "last" : "caan", "nationality" : "american", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27d"), "age" : 65, "dob" : "03/06/1925", "first" : "arnold", "gender" : "m", "hair_colour" : "brown", "last" : "schwarzenegger", "nationality" : "american", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27e"), "age" : 43, "dob" : "21/04/1978", "first" : "tony", "gender" : "m", "hair_colour" : "brown", "last" : "curtis", "nationality" : "american", "occupation" : "developer" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27f"), "age" : 22, "dob" : "22/11/1958", "first" : "jamie lee", "gender" : "f", "hair_colour" : "brown", "last" : "curtis", "nationality" : "american", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a280"), "age" : 45, "dob" : "14/03/1933", "first" : "michael", "gender" : "m", "hair_colour" : "brown", "last" : "caine", "nationality" : "english", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473cc9031ac66270a281"), "age" : 33, "dob" : "09/12/1934", "first" : "judi", "gender" : "f", "hair_colour" : "white", "last" : "dench", "nationality" : "english", "occupation" : "actress" }
$lt/$lte
db.gbin1.find( { "age" : { "$lt" : 40 } } );
运行以上命令,得到如下输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27b"), "age" : 18, "dob" : "21/04/1978", "first" : "matthew", "gender" : "m", "hair_colour" : "brown", "last" : "setter", "nationality" : "australian", "occupation" : "developer" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27f"), "age" : 22, "dob" : "22/11/1958", "first" : "jamie lee", "gender" : "f", "hair_colour" : "brown", "last" : "curtis", "nationality" : "american", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473cc9031ac66270a281"), "age" : 33, "dob" : "09/12/1934", "first" : "judi", "gender" : "f", "hair_colour" : "white", "last" : "dench", "nationality" : "english", "occupation" : "actress" }
如果需要查询年龄小于等于40的呢?运行如下:
db.gbin1.find( { "age" : { "$lte" : 40 } } );
输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27b"), "age" : 18, "dob" : "21/04/1978", "first" : "matthew", "gender" : "m", "hair_colour" : "brown", "last" : "setter", "nationality" : "australian", "occupation" : "developer" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27f"), "age" : 22, "dob" : "22/11/1958", "first" : "jamie lee", "gender" : "f", "hair_colour" : "brown", "last" : "curtis", "nationality" : "american", "occupation" : "actor" }
{ "_id" : ObjectId("4f2f473cc9031ac66270a281"), "age" : 33, "dob" : "09/12/1934", "first" : "judi", "gender" : "f", "hair_colour" : "white", "last" : "dench", "nationality" : "english", "occupation" : "actress" }
$gt/$gte
现在查询演员年龄大于47的,运行如下查询:
db.gbin1.find( { "age" : { "$gt" : 47 } } );
输出:
{ "_id" : ObjectId("4ef224bf0fec2806da6e9b29"), "age" : 65, "dob" : "03/06/1925", "first" : "arnold", "gender" : "m", "hair_colour" : "brown", "last" : "schwarzenegger", "nationality" : "american", "occupation" : "actor" }
如果包括47的呢?
db.gbin1.find( { "age" : { "$gte" : 47 } } );
输出:
{ "_id" : ObjectId("4ef224bf0fec2806da6e9b29"), "age" : 65, "dob" : "03/06/1925", "first" : "arnold", "gender" : "m", "hair_colour" : "brown", "last" : "schwarzenegger", "nationality" : "american", "occupation" : "actor" }
$in/$nin
如果查询指定规则的数据呢?这里我们看看那些人是演员或者开发者,为了更简单的查看,我们只返回姓和名:
db.gbin1.find( { 'occupation' : { '$in' : [ "actor", "developer" ] } }, { "first" : 1, "last" : 1 } );
输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27b"), "first" : "matthew", "last" : "setter" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27c"), "first" : "james", "last" : "caan" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27d"), "first" : "arnold", "last" : "schwarzenegger" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27e"), "first" : "tony", "last" : "curtis" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a27f"), "first" : "jamie lee", "last" : "curtis" }
{ "_id" : ObjectId("4f2f473bc9031ac66270a280"), "first" : "michael", "last" : "caine" }
可以看到我们可以使用$nin得到相反的结果:
db.gbin1.find( { 'occupation' : { '$nin' : [ "actor", "developer" ] } }, { "first" : 1, "last" : 1 } );
输出:
{ "_id" : ObjectId("4f2f473cc9031ac66270a281"), "first" : "judi", "last" : "dench" }
接下来我们组合一些运算符,比如,我们想查询所有是男性或者是开发人员,并且年纪小于40的人。如下:
db.gbin1.find( { $or : [ { "gender" : "m", "occupation" : "developer" } ], "age" : { "$gt" : 40 } }, { "first" : 1, "last" : 1, "occupation" : 1, "dob" : 1 } );
输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27e"), "dob" : "21/04/1978", "first" : "tony", "last" : "curtis", "occupation" : "developer" }
正则表单式
不清楚是否大家满足于此,我承诺帮助大家查询更加复杂高级的组合,这里我们使用正则表达式。这里我们查询所有名里以“ma"或者”to”开始并且姓里以“se"或者"de"开始的人。如下:
db.gbin1.find( { "first" : /(ma|to)*/i, "last" : /(se|de)/i } );
输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27b"), "age" : 18, "dob" : "21/04/1978", "first" : "matthew", "gender" : "m", "hair_colour" : "brown", "last" : "setter", "nationality" : "australian", "occupation" : "developer" }
{ "_id" : ObjectId("4f2f473cc9031ac66270a281"), "age" : 33, "dob" : "09/12/1934", "first" : "judi", "gender" : "f", "hair_colour" : "white", "last" : "dench", "nationality" : "english", "occupation" : "actress" }
以上查询中,我们在名中使用了一个正则表单如下:
"first" : /(ma|to)*/i
//i意味着我们使用了大小写区别的正则。
(ma|to)*意味我们匹配ma或者to开始的字符串。
如果你不熟悉”*“,它意味着匹配任何字符。同样,对于姓来说,我们也使用类似的正则。
还不是很清楚吗?我们尝试另外一个查询,这里我们查询所有名字为james或者jame并且是美国女性演员的数据。如下:
db.gbin1.find( { "first" : /(jam?e*)*/i, "gender" : "f", "occupation" : "actor", "nationality" : "american" } );
以上的正则表达式匹配:james,jamee,jamie等等。问好只匹配一个字符,a-z,A-Z,0-9。和前面一样,"*"匹配所有。
输出:
{ "_id" : ObjectId("4f2f473bc9031ac66270a27f"), "age" : 22, "dob" : "22/11/1958", "first" : "jamie lee", "gender" : "f", "hair_colour" : "brown", "last" : "curtis", "nationality" : "american", "occupation" : "actor" }
MapReduce
MapReduce是数据分析的重要角色。如果你没有听说过,简单说,MapReduce是拆分一个数据集合并且非配到一个电脑集群中来帮助缩短判断一个集合数据内容的方式和流程。
包括俩个部分:Map和Reduce。 实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(化简)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
如果你想了解更多,请查看: Wikipedia
MapReduce的例子:
让我们看看一个简单的例子。我们将分析我们的数据集,找到所有女性的数据个数。事实上,这是个很简单的例子,但是帮助你理解Mapreduce如何工作的。
Map函数
var map = function() {
emit( { gender: this.gender }, { count: 1 } );
}
输出:
{ 'f' : 1 }
Reduce函数
现在我们将他们组合使用,通过调用mapreduce函数。我们通过调用map和reduce函数来传递我们创建的map和reduce变量,指定数据结果保存的集合名称,这里是"gender",如下:
var res = db.gbin1.mapReduce( map, reduce, { out : 'gender' } );
输出内容
当map-reduce完毕,我们可以访问它。如下:
db.gender.find();
{ "_id" : { "gender" : "f" }, "value" : { "count" : 2 } }
当然,这里有其它的参数可以传递到mapReduce中来自定义
- sort - 排序输出内容
- limit - 限制返回的结果数
- out - 保存结果的集合名称
- finalise - 指定一个函数在reduction过程结束后运行
- scope - 指定在map, reduce和finalise函数中使用的变量
- jsMode - 避免一个中间步骤(在map和reduce之间)来恢复JSON数据格式
- verbose - 详细的执行过程
以上是一个基本高级mongdb的使用指南。希望能够帮助大家快速了解这个伟大的工具。