1. 介绍GUI(图形用户界面接口)数据库管理软件

选用rockmongo,这个GUI管理软件基于PHP的,所以先准备PHP运行环境。

安装步骤:
1.执行wampmanager.exe安装PHP集成环境。
 
下载RockMongo-on-Windowsv0.0.4.zip
1. 解压缩到D:\GUI_mongo
4.从cmd控制台先将mongo数据库连接上
控制台1:D:\mongo\bin>mongod–dbpath d:\data\db
控制台2:D:\mongo\bin>mongo
这样就能连接mongo数据库
5.找到D:\GUI_mongo\rockmongo-on-windows\rockstart.bat并执行之
6.第5步执行完,会自动从浏览器新开一个页面,让你去登陆数据库
用户名和密码都输入admin,数据库名可以留空,点击登陆按钮就能进入数据库管理界面。

导出功能:
导出默认路径:C:\Documentsand Settings\jimvin\My Documents
eg:
C:\Documentsand Settings\jimvin\My Documents\mongo-test-20131128-033947.js
以上导出文件为早前test数据表的信息,在mongodb执行里面包含的操作会给test表插入之前存在的所有记录。相当于数据表的sql文件。

  1. 高级查询

*数值类型的比较
1)大于
x>6

db.things.find({ "x": {$gt: 6} } )

意思:搜索things数据表,将字段x的值大于6的记录都搜出来。
2)小于
x<6

db.things.find({ "x": {$lt: 6} } )

意思:搜索things数据表,将字段x的值小于6的记录都搜出来。
3)大于等于
x>=6

db.things.find( { "x":{$gte: 6} } )

意思:搜索things数据表,将字段x的值大于等于6的记录都搜出来。
4)小于等于
x<=6

db.things.find( { "x":{$lte: 6} } )

5)区间搜索
5

db.things.find({ "x": {$gt: 5, $lt: 11} } )

5<=x<11

db.things.find({ "x": {$gte: 5, $lt: 11} } )

5<=x<=11

db.things.find({ "x": {$gte: 5, $lte: 11} } )

5

db.things.find({ "x": {$gt: 5, $lte: 11} } )

*判断是否匹配所有

db.things.find( { age: { $all:[7,8] } } )

意思:匹配age字段包含[7,8]的所有记录
匹配如下记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e7"),
"age": {
"0": 7,
"1": 8,
"2": 9
},
"x": 10,
"y": 9
}

db.things.find( { add:{ $all: [‘jimvin’,‘aaa’]} } )

匹配如下记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e5"),
"add": {
"0": "jimvin",
"1": "abc",
"2": "aaa"
},
"x": 6,
"y": 7
}
db.things.find({add: { $all: [{age:21, name:'jimvin'}, {age:22, name:'jimvin'}] } } )

匹配如下记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e2"),
"add": {
        "0": {
        "age": 21,
        "name": "jimvin"
        },
        "1": {
        "age": 22,
        "name": "jimvin"
        },
        "2": {
        "age": 23,
        "name": "jimvin"
        },
        "3": {
        "age": 23,
        "name": "jimvin"
        }
},
"x": 6,
"y": 4
}

*判断字段是否存在
1)将存在x字段的记录都搜出来

db.things.find( { "x":{$exists: true} } )

2)将不存在x字段的记录都搜出来

db.things.find({ "x": {$exists: false} } )

注意:在js中“”和‘’都是允许的(在JAVA中字符串类型或者字符类型都只能用“”,不能用‘’),在JSON数据中冒号前面的都会被解析器理解为属性名,即便我没有用“”和‘’给它引起来。所以如下所示也是可以的:

db.things.find({ x: {$exists: true} } )
db.things.find( { ‘x’:{$exists: true} } )

*Null值处理

db.things.find({age: null} )

匹配记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e4"),
"age": null,
"x": 6,
"y": 6 
}
{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e3"),
"x": 6,
"y": 5
}

从结果可以看出匹配两种类别记录:
1.没有age字段的记录
2.age字段被赋值为null的记录

引出问题:假如我想找出age字段被赋值为null的记录,该如何写?

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

写成如下

db.things.find( { age:{ $all:[null] , $exists: true } } )

会匹配所有具有age字段的记录,等价于

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

*取模运算
关键字:$mod

db.things.find({ num:{ $mod: [x,y] } } )

x表示与什么数进行取模
y表示取模后的结果
例子:

db.things.find( { num:{ $mod:[10,0] } } )

意思:找出num字段与10取模等于0的所有记录
匹配记录:

{
"_id": ObjectId("5296e6d68378a9afba69af46"),
"add": {
        "age": 20,
        "name": "jimvin"
        },
"num": 10
}
{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e6"),
"age": {
        "0": 7,
        "1": 9
        },
"num": 20,
"x": 6,
"y": 8
}

db.things.find({ num:{ $mod: [10,5] } } )

匹配记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e3"),
"num": 55,
"x": 6,
"y": 5
}
  • 不等于(数值类型和字符串类型都可以)
    关键字:$ne
db.things.find( { num:{ $ne: 10}} )

意思:搜出num字段不等于10的所有记录
注意:这里把没有num字段的记录也找出来了。

要找到包含num字段而且num又不等于10的记录:

db.things.find({ num:{ $ne: 10, $exists: true }} )

要找到包含name字段而且name又不等于‘jimvin’的记录:

db.things.find({ name: { $ne: 'jimvin', $exists: true } } )

*非(要与正则表达式配合一起使用的)
关键字:$not

db.things.find({ name:{ $not:/^t/, $exists: true }} )

意思是找出存在name字段,且name字段值不是以t字符开头的记录
匹配记录:

{
"_id": ObjectId("5296e6d68378a9afba69af46"),
"add": {
"age": 20,
"name": "jimvin" 
},
"name": "jim",
"num": 10 
}

不匹配记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e7"),
"age": {
"0": 7,
"1": 8,
"2": 9 
},
"name": "tom",
"x": 10,
"y": 9 
}

注意:与非正则表达式使用会出现异常

db.things.find({ num:{ $not: 10 }} )

报错:error:{“err":"invaliduseofnot”, “code” :13041 }

  • 包含
    关键字:$in
db.things.find( { num: { $in:[10,55] } } )

意思:找出num字段值为10或者55的记录

db.things.find({ num: { $in:[10, 55, null] } } )

意思:找出num字段值为10或者55的记录,和没有num字段或者num字段等于null的记录

*不包含
关键字:$nin

db.things.find( { num: {$nin:[10, 55] } } )

意思:找出num字段值既不等于在10也不等于55的记录,和没有num字段或者num字段等于null的记录

找出num字段值既不等于在10也不等于55的记录(num为null会被匹配),而且存在num字段:

db.things.find( { num: {$nin:[10, 55], $exists: true } } )

*数组元素个数
关键字:$size

db.things.find( { add: { $size: 3} } )

意思:找出add字段包含3个数组元素的记录
匹配记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e5"),
"add": {
"0": "jimvin",
"1": "abc",
"2": "aaa"
},
"x": 6,
"y": 7
}

db.things.find({ add: { $size: 4 } } )

匹配记录:

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e2"),
"add": {
"0": {
"age": 21,
"name": "jimvin"
},
"1": {
"age": 22,
"name": "jimvin"
},
"2": {
"age": 23,
"name": "jimvin"
},
"3": {
"age": 23,
"name": "jimvin"
}
},
"x": 6,
"y": 4
}

*where查询关键字:where

db.things.find( { $where:'this.num>9' } )

意思:将num字段大于9的记录全部找出来。

找出num字段等于“abc”的记录(没有num字段和num字段为null的记录不会被搜到)

db.things.find( { $where: "this.num == 'abc' " } )

找出num字段等于“abc”或55的记录

db.things.find( { $where: "this.num == 'abc' || this.num == 55 " } )

写成

db.things.find({ $where: " this.num == 'abc' || this.num == 55 "} )

也是没问题的,注意||两边各保留一个空格就行了。

注意:
1.等值判断,千万注意用==,不要使用赋值运算符=

db.things.find( { $where:'this.num=9' } )

这样写会返回所有记录。

2.假如你有以下记录

{
"_id": ObjectId("5296e6d68378a9afba69af46"),
"add": {
"age": 20,
"name": "jimvin"
},
"name": "jim",
"num": 10
}

{
"_id": ObjectId("528ec3042e2ec9f2c3cd55e4"),
"age": null,
"num": null,
"x": 6,
"y": 6
}

搜索语句写成:

db.things.find({ $where: 'this.add.age > 9' } )

报异常,如下

error:{
"$err":"TypeError: Cannot read property 'age' of undefined",
“code”:16722
}

原因是记录2没有add字段,所以this.add为undefined,undefined.age是存在js语法错误的,所以报错了。所以要特别注意在集合内是否每条记录都存在名为add的字段,这是最基本的。

*用函数方式做判断

f= function(){ return this.num > 9; }
db.things.find(f);

意思:将num字段大于9的记录全部找出来。
等价于

db.things.find( {$where: 'this.num>9' } )
db.things.find({ num: {$gt: 9} } )

*限制返回记录的起点

db.things.find().skip(3);

意思:从第四条记录开始,包括第四条记录,并显示剩余的所有记录

*查询记录条数

db.things.find().count()

返回12,在本机things集合里共有12条记录。

db.things.find().skip(3).count()

返回依旧为12,假如我想返回限制后的记录条数(12-3=9),应该写成如下:

db.things.find().skip(3).count(true)// true可以用非0的数替代

返回9.

db.things.find().skip(3).limit(2).count(true)

返回2

db.things.find().skip(12).limit(2).count(true)

返回0

*排序

db.things.find().sort({y: -1 })

意思:按y字段降序排列

db.things.find().sort({y: 1 })

意思:按y字段升序排列

注意:假如有一些记录不存在y字段,那会如何排呢?
答:测试结果显示,将不存在y字段的那些记录排在结果集的最后面,至于这些记录的先后顺序与正常排序时的先后顺序一致。

  • 游标
    作用:用于循环处理每一条结果数据,游标在所有数据库作用都是一样的。
for(var c=db.things.find();c.hasNext();){
    printjson( c.next() ); //c.next()已经做了修改循环指标的工作,所以for语句中的第三条语句可以省略
}

打印出的结果类似如下所示:从RockMongo中拷贝下来的。

{
"_id": ObjectId("5296e6d68378a9afba69af46"),
"add": {
"age": 20,
"name": "jimvin" 
},
"name": "jim",
"num": 10 
}

方式二:

varshow = function(value){ printjson(value); }
db.things.find().forEach(show );

注意在浏览器端的forEach语句,此处的show方法是接收3个参数
value:数组元素值
index:数组元素的索引
ar:数组本身
varshow = function(value,index,ar){ }
但在MongoDB中,传进show方法的只有一个参数,arguments.length为1

*存储过程
存储过程存储在一个集合中,这个集合为db.system.js,虽然看起来别扭,好像js文件,但实际上它是一个集合。

创建一个存储过程:
功能:搜索add字段包含两个以上数组元素的记录

var process = function(){
var c = db.things.find();
var results = [];
c.forEach(function(value){
    if( value.add instanceof Array && value.add.length >= 2 ){
        // printjson(value);
        results.push(value);
    }
});
return results;
}

db.system.js.save( { _id: "find", value: process } );

确认一下存储过程已经保存到system.js表中:

db.system.js.find();

显示如下:

{ "_id": "find", "value": function(){
var c = db.things.find();
var results = [];
c.forEach(function(value){
    if( value.add instanceof Array && value.add.length >= 2 ){
        // printjson(value);
        results.push(value);
    }
});
return results;
} }

运行存储过程:

db.eval('find()');

返回add字段包含两个以上数组元素的记录

注意:
1.假如我们将process替换为

var process = function(){
    var c = db.things.find();
    c.forEach(function(value){
    if( value.add instanceof Array && value.add.length >= 2 ){
        printjson(value);
    }
    });
}

里面没有任何值返回,尽管process()有东西打印出来,但是db.eval(‘find()’);返回的结果为null。所以要特别注意存储过程要返回结果集或者其他数据才有意义。

2.假如存储过程是一个函数字面量,不需要加“”,eg:

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

返回6
当然db.eval(‘function(){ return3+3;}’)也ok的

但db.eval(find())会报异常。
如下所示:find is notdefined

3.从用法得知,存储过程优点
1)查询更简单
2)封装了逻辑,减少出错的机会
3)性能更佳