| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
jopen
9年前发布

MongoDB 基本操作详解

MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语 言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。最后由于 MongoDB 可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受 到欢迎,很多项目都考虑用 MongoDB 来替代 MySQL 等传统数据库来实现不是特别复杂的 Web 应用。由于数据量实在太大,所以迁移到了 MongoDB 上面,数据查询的速度得到了非 常显著的提升。

MongoDB 基本操作详解

下面将介绍一些查询语法

1、 条件操作符

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

db.collection.find({ "field" : { $gt: value } } ); // 大于: field > value  db.collection.find({ "field" : { $lt: value } } ); // 小于: field < value  db.collection.find({ "field" : { $gte: value } } ); // 大于等于: field >= value  db.collection.find({ "field" : { $lte: value } } ); // 小于等于: field <= value

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

db.collection.find({ "field" : { $gt: value1, $lt: value2 } } ); // value1 < field < value

2、$all 匹配所有

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

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

可以查询出 {name: ‘David’, age: 26, age: [ 6, 8, 9 ] }
但查询不出 {name: ‘David’, age: 26, age: [ 6, 7, 9 ] }

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

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

db.users.find({age: {$exists: true}});

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

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

举例如下:

C1 表的数据如下:

>db.c1.find();  { "_id" : ObjectId("4fb4a773afa87dc1bed9432d"), "age" : 20, "length" : 30 }  { "_id" : ObjectId("4fb4a7e1afa87dc1bed9432e"), "age_1" : 20, "length_1" : 30 }

查询存在字段 age 的数据

> db.c1.find({age:{$exists:true}});  { "_id" : ObjectId("4fb4a773afa87dc1bed9432d"), "age" : 20, "length" : 30 }

可以看出只显示出了有 age 字段的数据, age_1 的数据并没有显示出来

4、Null 值处理

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

> db.c2.find()  { "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }  { "_id" : ObjectId("4fc34be01d8a39f01cc17ef5"), "name" : "Jacky", "age" : 23 }  { "_id" : ObjectId("4fc34c1e1d8a39f01cc17ef6"), "name" : "Tom", "addr" : 23 }

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

> db.c2.find({age:null})  { "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }  { "_id" : ObjectId("4fc34c1e1d8a39f01cc17ef6"), "name" : "Tom", "addr" : 23 }

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

> db.c2.find({age:{"$in":[null], "$exists":true}})  { "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }

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

5、$mod 取模运算

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

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

举例如下:

C1 表的数据如下:

> db.c1.find()  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

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

> db.c1.find({age: {$mod : [ 6 , 1 ] } })  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }

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

6、$ne 不等于

查询 x 的值不等于 3 的数据

db.things.find( { x : { $ne : 3 } } );

举例如下:

C1 表的数据如下:

> db.c1.find()  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

查询 age 的值不等于 7 的数据

> db.c1.find( { age : { $ne : 7 } } );  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

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

7、$in 包含

与 sql 标准语法的用途是一样的,即要查询的是一系列枚举值的范围内查询 x 的值在 2,4,6 范围内的数据db.things.find({x:{$in: [2,4,6]}});

举例如下:

C1 表的数据如下:

> db.c1.find()  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

查询 age 的值在 7,8 范围内的数据

> db.c1.find({age:{$in: [7,8]}}); { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }

可以看出只显示出了 age 等于 7 或 8 的数据,其它不符合规则的数据并没有显示出来

8、$nin 不包含

与 sql 标准语法的用途是一样的,即要查询的数据在一系列枚举值的范围外查询 x 的值在 2,4,6 范围外的数据

db.things.find({x:{$nin: [2,4,6]}});

举例如下:

C1 表的数据如下:

> db.c1.find()  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

查询 age 的值在 7,8 范围外的数据

> db.c1.find({age:{$nin: [7,8]}});  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

可以看出只显示出了 age 不等于 7 或 8 的数据,其它不符合规则的数据并没有显示出来

9、$size 数组元素个数

对于{name: ‘David’, age: 26, favorite_number: [ 6, 7, 9 ] }记录匹配 db.users.find({favorite_number: {$size: 3}});不匹配 db.users.find({favorite_number: {$size: 2}});

举例如下:

C1 表的数据如下:

> db.c1.find()  { "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }  { "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

查询 age 的值在 7,8 范围外的数据

> db.c1.find({age:{$nin: [7,8]}});  { "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }

可以看出只显示出了 age 不等于 7 或 8 的数据,其它不符合规则的数据并没有显示出来

10、正则表达式匹配

查询不匹配 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 的数据,其它不符合规则的数据并没有显示出来

11、Javascript 查询和$where 查询

查询 a 大于 3 的数据,下面的查询方法殊途同归

 db.c1.find( { a : { $gt: 3 } } );   db.c1.find( { $where: "this.a > 3" } );   db.c1.find("this.a > 3");   f = function() { return this.a > 3; } db.c1.find(f);

12、count 查询记录条数

count 查询记录条数db.users.find().count();

以下返回的不是 5,而是 user 表中所有的记录数量

db.users.find().skip(10).limit(5).count();

如果要返回限制之后的记录数量,要使用 count(true)或者 count(非 0)

db.users.find().skip(10).limit(5).count(true);

举例如下:

C1 表的数据如下:

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

查询 c1 表的数据量

> db.c1.count()  2

可以看出表中共有 2 条数据

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

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

db.users.find().skip(3).limit(5);

举例如下:

C1 表的数据如下:

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

查询 c1 表的第 2 条数据

> db.c1.find().skip(1).limit(1)  { "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }

可以看出表中第 2 条数据被显示了出来

14、sort 排序

以年龄升序 asc

db.users.find().sort({age: 1});

以年龄降序 desc

db.users.find().sort({age: -1});

C1 表的数据如下:

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

查询 c1 表按 age 升序排列

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

第 1 条是 age=10 的,而后升序排列结果集

查询 c1 表按 age 降序排列

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

第 1 条是 age=20 的,而后降序排列结果集

15、游标

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

> for( var c = db.t3.find(); c.hasNext(); ) {  ... printjson( c.next());  ... }  { "_id" : ObjectId("4fb8e4838b2cb86417c9423a"), "age" : 1 }  { "_id" : ObjectId("4fb8e4878b2cb86417c9423b"), "age" : 2 }  { "_id" : ObjectId("4fb8e4898b2cb86417c9423c"), "age" : 3 }  { "_id" : ObjectId("4fb8e48c8b2cb86417c9423d"), "age" : 4 }  { "_id" : ObjectId("4fb8e48e8b2cb86417c9423e"), "age" : 5 }

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

> db.t3.find().forEach( function(u) { printjson(u); } );  { "_id" : ObjectId("4fb8e4838b2cb86417c9423a"), "age" : 1 }  { "_id" : ObjectId("4fb8e4878b2cb86417c9423b"), "age" : 2 }  { "_id" : ObjectId("4fb8e4898b2cb86417c9423c"), "age" : 3 }  { "_id" : ObjectId("4fb8e48c8b2cb86417c9423d"), "age" : 4 }  { "_id" : ObjectId("4fb8e48e8b2cb86417c9423e"), "age" : 5 }  >

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; }});

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

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

这样看起来还不错,下面我看来实际调用一下这个存储过程:

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

这样的操作方法简直太简单了 ,也许这就是 MongoDB 的魅力所在。
db.eval()是一个比较奇怪的东西,我们可以将存储过程的逻辑直接在里面并同时调用,而无需事先声明存储过程的逻辑。

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

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

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

 本文由用户 jopen 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1439802972520.html
MongoDB NoSQL数据库