MongoDB 第5章 MongoDB高级查询(mongodb数据库)

网友投稿 735 2022-05-30

本章将结合实际应用,重点阐述一些实际工作中最常用的方法。

面向文档的NoSQL数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具有良好的查询性能。

MongoDB最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

最后由于MongoDB可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎,很多项目都考虑用MongoDB来替代MySQL等传统数据库来实现不是特别复杂的web应用,由于数据量实在太大,所以迁移到MongoDB上面,数据查询的速度得到非常显著显著提升。

下面将介绍一些高级查询语法。

1.1.、条件操作符

<、<=、>、>=这几个操作符不用多解释了,最常用的也是最简单的。

> db.xuz.find({"j":{$gt:10}}); //大于:field>value

{ "_id" : ObjectId("54a8a620e708df7187eb2de2"), "x" : 5, "j" : 11 }

{ "_id" : ObjectId("54a8a620e708df7187eb2de3"), "x" : 5, "j" : 12 }

{ "_id" : ObjectId("54a8a620e708df7187eb2de4"), "x" : 5, "j" : 13 }

> db.xuz.find({"j":{$lt:10}});//小于:field

{ "_id" : ObjectId("54a8a5a427681683ca2c2466"), "x" : 5, "j" : 1 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2467"), "x" : 5, "j" : 2 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2468"), "x" : 5, "j" : 3 }

> db.xuz.find({"j":{$gte:10}});//大于等于:field>=value

{ "_id" : ObjectId("54a8a5a427681683ca2c246f"), "x" : 5, "j" : 10 }

{ "_id" : ObjectId("54a8a620e708df7187eb2de1"), "x" : 5, "j" : 10 }

{ "_id" : ObjectId("54a8a620e708df7187eb2de2"), "x" : 5, "j" : 11 }

{ "_id" : ObjectId("54a8a620e708df7187eb2de3"), "x" : 5, "j" : 12 }

> db.xuz.find({"j":{$lte:10}});//小于等于:field<=value

{ "_id" : ObjectId("54a8a5a427681683ca2c2466"), "x" : 5, "j" : 1 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2467"), "x" : 5, "j" : 2 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2468"), "x" : 5, "j" : 3 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2469"), "x" : 5, "j" : 4 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246a"), "x" : 5, "j" : 5 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246b"), "x" : 5, "j" : 6 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246c"), "x" : 5, "j" : 7 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246d"), "x" : 5, "j" : 8 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246e"), "x" : 5, "j" : 9 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246f"), "x" : 5, "j" : 10 }

如果要同时满足多个条件,可以这样做。

> db.xuz.find({"j":{$gt:5,$lt:10}});//value1

{ "_id" : ObjectId("54a8a5a427681683ca2c246b"), "x" : 5, "j" : 6 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246c"), "x" : 5, "j" : 7 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246d"), "x" : 5, "j" : 8 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246e"), "x" : 5, "j" : 9 }

1.2、$all匹配所有

这个操作符跟SQL语法的in类似,但不同的是,in只需满足()内的某一个值即可,而$all必须满足[]内的所有值,比如:

> db.xuz.find({age:{$all:[6,8]}})

{ "_id" : ObjectId("54a8bc71587fb1134affd9cf"), "name" : "zhangsan", "age" : [ 6, 7, 8 ] }

但是查询不出

{ "_id" : ObjectId("54a8bc71587fb1134affd9cf"), "name" : "zhangsan", "age" : [ 6, 7, 9] }

1.3、$exists判断字段是否存在

查询所有存在的age字段的记录:

> db.xuz.find({age:{$exists:true}})

{ "_id" : ObjectId("54a8bc71587fb1134affd9cf"), "name" : "zhangsan", "age" : [ 6, 7, 8 ] }

{ "_id" : ObjectId("54a8bc76587fb1134affd9d0"), "name" : "zhangsan", "age" : [ 6, 7, 9 ] }

>

查询所有不存在name字段的记录:

> db.xuz.find({name:{$exists:false}});

{ "_id" : ObjectId("54a8a5042db3e1b27d0e5204"), "x" : 4 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2466"), "x" : 5, "j" : 1 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2467"), "x" : 5, "j" : 2 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2468"), "x" : 5, "j" : 3 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2469"), "x" : 5, "j" : 4 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246a"), "x" : 5, "j" : 5 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246b"), "x" : 5, "j" : 6 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246c"), "x" : 5, "j" : 7 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246d"), "x" : 5, "j" : 8 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246e"), "x" : 5, "j" : 9 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246f"), "x" : 5, "j" : 10 }

再比如:c1表的数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

查询存在age字段的数据

> db.c1.find({age:{$exists:true}})

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

只能显示出有age字段的数据,age_1的数据并没有显示出来。

1.4、NULL值处理

NULL值的处理稍微有一点奇怪,具体看下面的样例数据:

> db.c2.find();

{ "_id" : ObjectId("54a8bde4587fb1134affd9d3"), "nage" : "wangwu", "age" : null }

{ "_id" : ObjectId("54a8bdf7587fb1134affd9d4"), "name" : "zhangsan", "age" : 23 }

{ "_id" : ObjectId("54a8be09587fb1134affd9d5"), "name" : "zhaoliu", "addr" : 23 }

其中wangwu的age字段为空,zhaoliu没有age字段,我们想找到age为空的行,具体如下:

> db.c2.find({age:null})

{ "_id" : ObjectId("54a8bde4587fb1134affd9d3"), "nage" : "wangwu", "age" : null }

{ "_id" : ObjectId("54a8be09587fb1134affd9d5"), "name" : "zhaoliu", "addr" : 23 }

但是我们以为只能找到wangwu,却zhaoliu也被找出来了,所以null不仅能找到它自身,连不存在的age字段的记录也找出来了,那么怎么样才能只找到wangwu呢?我们用exists来限制一下即可:

> db.c2.find({age:{$in:[null],$exists:true}})

{ "_id" : ObjectId("54a8bde4587fb1134affd9d3"), "nage" : "wangwu", "age" : null }

这样如我们期望一样,只有wangwu被找出来了。

1.5、$mod取模运算

查询age取模10等于0的数据

> db.c1.find({age:{$mod:[10,0]}})

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

在比如,c1表数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

查询age取模10等于1的数据

> db.c1.find({age:{$mod:[10,1]}})

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

可以看出只显示出了age取模10等于1的数据,其他不符合规则的数据并没有显示出来。

1.6、$ne不等于

查询age的值不等于20的数据。

c1表的数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

查询age的值不等于20的数据。

> db.c1.find({age:{$ne:20}})

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

可以看出只显示出了age不等于20的数据,其他不符合规则的数据并没有显示出来。

1.7、$in包含

与SQL标准语法的用途一样,即要查询的是一系列的枚举值的范围。

比如c1表的数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

查询age的值在21,22范围内的数据。

> db.c1.find({age:{$in:[21,22]}})

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

可以看出只显示出了age等于21或者22的数据,其他不符合规则的数据并没有显示出来。

1.8、$nin不包含

与SQL标准语法的用途是一样的,既要查询的数据在一系列的枚举范围外。

比如c1表的数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

查询age的值在21,22范围外的数据

> db.c1.find({age:{$nin:[21,22]}})

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

可以看出只显示出了age不等于21或者22的数据,其他不符合规则的数据并没有显示出来。

1.9、$size数组元素的个数

对于c3表的数据如下:

> db.c3.find();

{ "_id" : ObjectId("54a8c156587fb1134affd9d8"), "age" : [ 6, 7, 8 ] }

{ "_id" : ObjectId("54a8c160587fb1134affd9d9"), "age" : [ 6, 7 ] }

{ "_id" : ObjectId("54a8c163587fb1134affd9da"), "age" : [ 6, 7, 9 ] }

{ "_id" : ObjectId("54a8c166587fb1134affd9db"), "age" : [ 6, 7, 9, 10 ] }

查询age字段size为3的记录:

> db.c3.find({age:{$size:3}})

{ "_id" : ObjectId("54a8c156587fb1134affd9d8"), "age" : [ 6, 7, 8 ] }

{ "_id" : ObjectId("54a8c163587fb1134affd9da"), "age" : [ 6, 7, 9 ] }

可以看出只显示出了age的size为3的数据,其他不符合规则的数据并没有显示出来。

1.10、正则表达式

对于c4表数据如下:

> db.c4.find();

{ "_id" : ObjectId("54a8c1e6587fb1134affd9dc"), "name" : "Boy" }

{ "_id" : ObjectId("54a8c1eb587fb1134affd9dd"), "name" : "Tom" }

{ "_id" : ObjectId("54a8c1ef587fb1134affd9de"), "name" : "Joe" }

查询name不以B开头的数据:

> db.c4.find({name:{$not:/^T.*/}})

{ "_id" : ObjectId("54a8c1e6587fb1134affd9dc"), "name" : "Boy" }

{ "_id" : ObjectId("54a8c1ef587fb1134affd9de"), "name" : "Joe" }

可以看出只显示出了name不等于Boy的数据,Boy的数据并没有显示,因为它符合查询规则。

1.11、JavaScript查询和$where查询

比如c1表的数据如下:

> db.c1.find()

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

查询age大于20的数据,下面各种方法殊途同归。

> db.c1.find({age:{$gt:20}})

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

> db.c1.find({$where:"this.age>20"})

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

> db.c1.find("this.age>20")

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

function (){return this.age>20;}

> db.c1.find(f);

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

1.12、count查询记录条数

count查询记录条数。

> db.c1.find().count();

4

返回c1表中所有数据的记录数。

1.13、skip限制返回记录的起点

从3条记录开始,返回5条记录(limit3,5)

xuz表中总共有64条数据:

> db.xuz.find().count();

64

从第三条开始,查询出5条记录:

> db.xuz.find().skip(3).limit(5)

{ "_id" : ObjectId("54a8a5a427681683ca2c2468"), "x" : 5, "j" : 3 }

{ "_id" : ObjectId("54a8a5a427681683ca2c2469"), "x" : 5, "j" : 4 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246a"), "x" : 5, "j" : 5 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246b"), "x" : 5, "j" : 6 }

{ "_id" : ObjectId("54a8a5a427681683ca2c246c"), "x" : 5, "j" : 7 }

>

该实现在应用中可用于分页查询。

1.14、sort排序

c1表中数据如下:

> db.c1.find();

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

MongoDB 第5章 MongoDB高级查询(mongodb数据库)

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

以年龄升序asc排序:

> db.c1.find().sort({age:1})

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

以年龄降序排序:

> db.c1.find().sort({age:-1})

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{ "_id" : ObjectId("54a8bd51587fb1134affd9d2"), "age_1" : 20, "length_1" : 30 }

1.15、游标

像大多数数据库产品一样,MongoDB也是用游标来循环处理每一条结果数据,具体语法如下:

> for(var c=db.c1.find();c.hasNext();){printjson(c.next())}

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{

"_id" : ObjectId("54a8bd51587fb1134affd9d2"),

"age_1" : 20,

"length_1" : 30

}

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

MongoDB还有另外一种方式来处理游标

> db.c1.find().forEach(function(u){printjson(u);})

{ "_id" : ObjectId("54a8bd47587fb1134affd9d1"), "age" : 20, "length" : 30 }

{

"_id" : ObjectId("54a8bd51587fb1134affd9d2"),

"age_1" : 20,

"length_1" : 30

}

{ "_id" : ObjectId("54a8bf2b587fb1134affd9d6"), "age" : 21, "length" : 31 }

{ "_id" : ObjectId("54a8bf31587fb1134affd9d7"), "age" : 22, "length" : 35 }

>

1.16、存储过程

MongoDB为很多问题提供了一系列的解决方案,针对于其他数据库特性,它仍然毫不逊色,表现非比寻常。

MongoDB同样支持存储过程,关于存储过程你需要知道的第一件事就是它是用javaScript来些的,也许这会让你很奇怪,为什么它用javaScript来写,但实际上它会让你非常满意,MongoDB存储过程是存储在db.system.js表中,我们想象一个简单的sql自定义函数如下:

function addNumbers(x,y){

return x+y;

}

下面我们将这个SQL自定义函数转换为MongoDB的存储过程:

> db.system.js.save({_id:"addNumbers",value:function(x,y){return x+y;}});

WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "addNumbers" })

>

存储过程可以被查看,修改和删除,所以我们用find来查看一下是否这个存储过程已经被创建上了。

> db.system.js.find();

{ "_id" : "addNumbers", "value" : function (x,y){return x+y;} }

>

下面我们来实际调用一下这个存储过程:

> db.eval('addNumbers(3,4.2)');

7.2

>

db.eval()是一个比较奇怪的东西,我们可以将存储过程的逻辑直接在里面并同时调用,而无需事先声明存储过程的逻辑。

> db.eval(function(){return 3+2;});

5

>

从上面可以看出,MongoDB的存储过程可以方便的完成算术运算,但其它数据库产品在存储过程中可以处理数据库内部的一些事情,比如取出某张表的数据量等等操作,这些MongoDB能做到吗?答案是肯定的,MongoDB可以轻而易举的实现,如下实例:

> db.system.js.save({_id:"get_count",value:function(){return db.c1.count();}});

WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "get_count" })

> db.eval('get_count()')

4

可以看到存储过程可以很轻松的操作表。

至此MongoDB的高级查询相关的一些特性介绍完毕。

MongoDB SQL 数据库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:excel表格添加两个斜杠的方法步骤(怎样在excel表格里添加两个斜杠)
下一篇:vim&nbsp;命令大全&nbsp;/&nbsp;vi&nbsp;命令大全(vim保存退出命令)
相关文章