3.2 查询语法
MongoDB最大的特点是,它支持的查询语言非常强大,其语法类似于面向对象的查询语言,不但可以实现关系型数据库查询的大部分功能,而且还支持对数据建立索引。由于MongoDB可以支持非常复杂的数据结构,同时带有强大的数据查询功能,因此非常受欢迎,很多项目都考虑用MongoDB来替代MySQL等传统数据库来实现复杂的Web应用。很多案例都是因为数据量实在太大,所以迁移到MongoDB上,从而数据查询的速度得到了非常显著的提升。
3.2.1 数组内容的查询
MongoDB本身支持数组类型的内嵌对象,接下来讲解如何查询数组中的特定内容。
数组内容的查询方法跟普通查询方法没有区别,只不过要查询的是数组中的值,而不是单独的值。
例如数据库中的c1表,其中colors列存储的就是一个数组,如下面代码所示:

> db.c1.find()
{ "_id" : ObjectId("4ff00d91a4ea64ce4cafef7b"), "colors" : [ "red", "black" ] }
{ "_id" : ObjectId("4ff00da5a4ea64ce4cafef7c"), "colors" : [ "blue", "yellow" ] }
>
现在要查询colors中有red的记录,可以如下面的代码所示:
> db.c1.find( { colors : "red" } )
{ "_id" : ObjectId("4ff00d91a4ea64ce4cafef7b"), "colors" : [ "red", "black" ] }
>

结果跟我们期望的一样,包含“red”的记录出现了。
3.2.2 内嵌文档的查询
如果某一列存储的不是一个单独的值,而是一条有多个列的记录,这条记录叫做“内嵌文档”。所以查询内嵌文档时,需要将条件细化到列上。
例如,数据库中存在以下内嵌式文档数据,其中author列的值对应的就是内嵌文档。

> db.c2.find()                                                                                          
{ "_id" : ObjectId("4ff00eb1a4ea64ce4cafef80"), 
  "author" : { "name" : "Dan Brown", "age" : 38 }, 
  "book" : "The Lost Symbol" }
{ "_id" : ObjectId("4ff00eeca4ea64ce4cafef81"), 
  "author" : { "name" : "wangwenlong", "age" : 30 }, 
  "book" : "How greate the MongoDB!" }
>
现在查询“author=wangwenlong”的记录,可以如下面的代码所示:
> db.c2.find( { "author.name" : "wangwenlong" } );
{ "_id" : ObjectId("4ff00eeca4ea64ce4cafef81"), 
  "author" : { "name" : "wangwenlong", "age" : 30 }, 
  "book" : "How greate the MongoDB!" }
>

结果跟我们期望的一样,“author”是“wangwenlong”的记录出现了。
注意 查询内嵌对象的属性时,记得要加上引号("")。也就是说,字段是"author.name",而不是author.name。
3.2.3 正则表达式匹配
正则表达式就是用某种模式去匹配一类字符串的一个公式,它由一些普通的字符组成。
接下来讲解如何使用正则表达式来进行模糊查询。例如,查询不匹配“name=B*”开头的记录,如下面的代码所示:

db.users.find({name: {$not: /^B.*/}});

举一个实际的例子,c1表的数据如下面的代码所示:

> db.c1.find();
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }

查询name不以“T”开头的数据如下面的代码所示:

> db.c1.find({name: {$not: /^T.*/}})
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }

可以看出,只显示“name=Tony”的数据,其他不符合规则的数据并没有显示出来。
3.2.4 $where查询
$where查询允许在查询里执行JavaScript表达式。例如查询a大于3的数据,可以用普通的查询方法,如下面的代码所示:
db.c1.find( { a : { $gt: 3 } } );
注意 “$where查询”是指采用类似于SQL中的where语句来进行查询的方式,但命令中并不包含where关键字。
也可以用$where的数值比较符号来查询,如下面的代码所示:
db.c1.find("this.a > 3");
但有一点需要注意,如非必要,尽量不要使用,因为一旦使用,document都必须从BSON转换为一个JavaScript对象,所以$where查询比一般的查询会慢很多。