mongoDB

//首先基于 本 工具, 上面应选择连接, 和 对应的数据库, 以此来确认工作空间, 否则报错 , 
//monogodb 类似 js 的语法
//=========================================  数据库=======================================================
use runoob; //创建数据库
switched to db runoob;
show dbs;
db.dropDatabase();//删除数据库
//==========================================  集合 =======================================================
db.createCollection("runoob");
db.createCollection("mycol", { capped:true, autoIndexId:true, size:6142800, max:10000 } );
db.mycol2.insert({"name" : "菜鸟教程"}); //插入数据自动创建集合
show collections;
db.mycol2.drop();
//==========================================  插入文档 ====================================================
db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});
db.col.find();
//第二种先定义变量 后 插入
document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});
db.col.insert(document)
WriteResult({ "nInserted" : 1 });

//3.2版本后的 语法
db.collection.insertOne({"a": 3}) ;//向指定集合中插入一条文档数据
db.collection.insertMany([{"b": 3}, {'c': 4}]);//向指定集合中插入多条文档数据

//数组插入的方式
var arr = [];
for(var i=1 ; i<=20000 ; i++){
    arr.push({num:i});
}

db.numbers.insert(arr);

//==========================================  更新文档 ==============================================
//语法
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
) ;
//参数说明:
//query : update的查询条件,类似sql update查询内where后面的。
//update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
//upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
//multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
//writeConcern :可选,抛出异常的级别。
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}}) //更新一条
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi: true}) //更新多条
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   // 输出信息

db.col.save({		//这种方式根据 _id 判断,集合中存在则更新,否则插入
    "_id" : ObjectId("56064f89ade2f21f36b03136"),
    "title" : "MongoDB",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "Runoob",
    "url" : "http://www.runoob.com",
    "tags" : [
            "mongodb",
            "NoSQL"
    ],
    "likes" : 110
});

db.col.find().pretty();

//==========================================  删除文档 =================================================
//语法
db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
);
//参数说明:
//query :(可选)删除的文档的条件。
//justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
//writeConcern :(可选)抛出异常的级别。

db.col.remove({'title':'MongoDB 教程'});
db.col.remove({});//删除所有数据  (类似常规 SQL 的 truncate 命令):

//==========================================  查询文档 ===================================================
//语法
db.collection.find(query, projection);
//参数说明
//query :可选,使用查询操作符指定查询条件
//projection: 可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。

db.col.find().pretty();//易读的方式来显示所有文档
db.col.findOne();//

db.col.find({"by":"菜鸟教程"}).pretty(); //where by = '菜鸟教程';
db.col.find({"likes":{$lt:50}}).pretty(); //where likes < 50;
db.col.find({"likes":{$lte:50}}).pretty();//where likes <= 50;
db.col.find({"likes":{$gt:50}}).pretty();//where likes > 50;
db.col.find({"likes":{$gte:50}}).pretty();//where likes >= 50;
db.col.find({"likes":{$ne:50}}).pretty();//where likes != 50;

//and 语法
db.collection.find({key1:value1,key2:value2}).pretty();
db.col.find({"by":"菜鸟教程","title":"MongoDB教程"}).pretty();
//or 语法
db.col.find({$or:[{key1: value1}, {key2:value2}]});
db.col.find({$or:[{"by":"菜鸟教程"},{"title":"MongoDB教程"}]});
//and 和 or 联合使用
db.col.find({"likes":{$gt:50},$or:[{"by":'菜鸟教程'},{'title':"MongoDB 教程"}]}).pretty();

//==========================================  条件操作符 ==============================================
$gt -------- greater than  >
$gte --------- gt equal  >=
$lt -------- less than  <
$lte --------- lt equal  <=
$ne ----------- not equal  !=
$eq  --------  equal  =

//模糊查询  其实这个里是正则方式的一种运用
db.col.find({title:/教/});//查询 title 包含"教"字的文档
db.col.find({title:/^教/});//查询 title 字段以"教"字开头的文档
db.col.find({title:/教$/});//查询 titl e字段以"教"字结尾的文档

//============多条件查询===================
db.workmate.find({$and:[{age:{$gte:30}},{"skill.skillThree":'PHP'}]}, //相当于 where age>=30 and skill.skillThree='PHP'
    {name:1,"skill.skillThree":1,age:1,_id:0}
)

db.workmate.find({$or:[{age:{$gte:30}},{"skill.skillThree":'PHP'}]},
    {name:1,"skill.skillThree":1,age:1,_id:0}
)

db.workmate.find({age:{$in:[25,33]}},
    {name:1,"skill.skillOne":1,age:1,_id:0}
)

db.workmate.find({age:{$not:{$lte:30,$gte:20}}},
{name:1,"skill.skillOne":1,age:1,_id:0}
)

//============条件操作符 $type ============  根据类型筛选文件
//MongoDB中可以使用的类型如下表示:
类型								数字		备注
Double							1	 
String							2	 
Object							3	 
Array								4	 
Binary data					5	 
Undefined						6				已废弃。
Object id						7	 
Boolean							8	 
Date								9	 
Null								10	 
Regular Expression 	11	 
JavaScript					13	 
Symbol							14	 
JavaScript (with scope)	15	 
32-bit integer			16	 
Timestamp						17	 
64-bit integer			18	 
Min key							255			Query with -1.
Max key							127

//例如: 如何向获取 col 集合中title 为 String类型的数据,你可以使用以下命令:
db.col.find({"title":{$type:2}});
//或
db.col.find({"title":{$type:'string'}});

//$where ===================================
//$where操作符功能强大且灵活,它可以将JavaScript表达式的字符串或JavaScript函数作为查询语句的一部分。
//在JavaScri pt表达式和函数中,可以使用this或obj来引用当前操作的文档。
//JavaScript表达式或函数返回值为true时,才会返回当前的文档。
//查询时,$where操作符不能使用索引,每个文档需要从BSON对象转换成JavaSript对象后,才可以通过$where表达式来运行。
//因此,它比常规查询要慢很多,一般情况下,要避免使用$where查询。
db.getCollection('test_user').find({'$where':"function(){ return this.addresss.length>2}"});
上述等价:db.getCollection('test_user').find({'$where':"this.addresss.length>2"});

//in 和 not in ($in $nin)===================
db.collection.find( { "field" : { $in : array } } );

//取模运算$mod==============================取模查询的列必须是数字类型的,其他类型不行,能进行取模计算的类型查询才能有作用
db.things.find( "this.a % 10 == 1")
//可用$mod代替:
db.things.find( { a : { $mod : [ 10 , 1 ] } } )

//$all======================================
//和$in类似,但是他需要匹配条件内所有的值:
{ a: [ 1, 2, 3 ] }
//下面这个条件是可以匹配的:
db.things.find( { a: { $all: [ 2, 3 ] } } );
//但是下面这个条件就不行了:
db.things.find( { a: { $all: [ 2, 3, 4 ] } } );

//$size=====================================
//是匹配数组内的元素数量的,如有一个对象:{a:["foo"]},他只有一个元素:
//下面的语句就可以匹配:  但不能范围匹配
db.things.find( { a : { $size: 1 } } );

//$exists===================================
//$exists用来判断一个元素(字段)是否存在:
db.things.find( { a : { $exists : true } } ); // 如果存在元素a,就返回
db.things.find( { a : { $exists : false } } ); // 如果不存在元素a,就返回


//==========================================  limit() 和 Skip() =============================================
//limit()语法 limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
db.COLLECTION_NAME.find().limit(NUMBER);
//代表无参,只返回两条数据 的4个属性 (属性后面的值 >0 代表显示,这里因为_id 比较特殊只有这只为0才不会显示)
db.col.find({},{"title":1,'by':1,'likes':1,_id:0}).limit(2) ;


//Skip()语法 使用skip()方法来跳过指定数量的数据,skip方法接受一个数字参数作为跳过的记录条数,默认参数为0
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER);
//以下实例只会显示第二条文档数据
db.col.find({},{"title":1,_id:0}).limit(1).skip(1);

//==========================================  limit() 和 Skip() ===============================================
//sort() 语法  //其中 1 为升序排列,而 -1 是用于降序排列。
db.COLLECTION_NAME.find().sort({KEY:1})
//样例:演示col集合中的数据按字段 likes的降序排序
db.col.find({},{"title":1,'likes':1,_id:0}).sort({"likes":-1});


//==========================================  索引 =============================================================
//创建索引     
db.collection.createIndex(keys, options);
//语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

db.col.createIndex({'title': 1}); //升序创建 title索引
db.col.createIndex({"title":1,"description":-1});//创建多字段 复合索引
db.values.createIndex({'open': 1, 'close': 1}, {background: true});//后台创建索引,避免创建索引阻塞其他数据库操作
1、查看集合索引
db.col.getIndexes()
2、查看集合索引大小
db.col.totalIndexSize()
3、删除集合所有索引
db.col.dropIndexes()
4、删除集合指定索引
db.col.dropIndex("索引名称")
5、设置定时删除集合中的数据
//利用 TTL 集合对存储的数据进行失效时间设置:经过指定的时间段后或在指定的时间点过期,MongoDB 独立线程去清除【数据】。
5.1、设置时间180秒后自动清除。设置在创建记录后,180秒左右删除
db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180});
5.1、//设置 A 记录在 2019 年 1 月 22 日晚上 11 点左右删除,
	 //A 记录中需添加 "ClearUpDate": new Date('Jan 22, 2019 23:00:00'),且 Index中expireAfterSeconds 设值为 0。
db.col.createIndex({"ClearUpDate": 1},{expireAfterSeconds: 0})
// 索引关键字段必须是 Date 类型。
// 非立即执行:扫描 Document 过期数据并删除是独立线程执行,默认 60s 扫描一次,删除也不一定是立即删除成
//==========================================  聚合 =============================================================

//MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*)

//aggregate() 方法的基本语法格式如下所示:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]);  //$group 第一个参数_id 名为固定写法
{
   "result" : [
      {
         "_id" : "runoob.com",
         "num_tutorial" : 2
      },
      {
         "_id" : "Neo4j",
         "num_tutorial" : 1
      }
   ],
   "ok" : 1
}

//以上实例类似sql语句:
 select by_user, count(*) from mycol group by by_user

下表展示了一些聚合的表达式:

表达式												描述						实例
//$sum													计算总和。	
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])

//$avg													计算平均值	
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])

//$min													获取集合中所有文档对应值得最小值。	
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])

//$max													获取集合中所有文档对应值得最大值。	
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])

//$push													在结果文档中插入值到一个数组中。 就是分组结果放在一个集合里的意思	
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])

//$addToSet											在结果文档中插入值到一个数组中,但不创建副本。就是分组结果放在一个集合里并去重的意思	
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])

//$first												根据资源文档的排序获取第一个文档数据。	
db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])

//$last													根据资源文档的排序获取最后一个文档数据	
db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])


// 管道的概念 ===================
//管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
//
//MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
//
//表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
//
//这里我们介绍一下聚合框架中常用的几个操作:
//
$project:	修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:		用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:		用来限制MongoDB聚合管道返回的文档数。
$skip:			在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:		将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:		将集合中的文档分组,可用于统计结果。
$sort:			将输入文档排序后输出。
$geoNear:	输出接近某一地理位置的有序文档。


//管道操作符实例
1、$project实例
db.article.aggregate({ $project : { title : 1 ,author : 1 ,}});
//这样的话结果中就只含有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
db.article.aggregate({ $project : {_id : 0 ,title : 1 ,author : 1}});

2.$match实例
db.articles.aggregate( [
                        { $match : { score : { $gt : 70, $lte : 90 } } },
                        { $group: { _id: null, count: { $sum: 1 } } }
                       ] );
//$match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。

3.$skip实例
db.article.aggregate({ $skip : 5 });
//经过$skip管道操作符处理后,前五个文档被"过滤"掉。


//=====================================  复制(副本集)其实就是主从复制,读写分离 =====================================

自行百度 

//=====================================  分片===========================================================================

自行百度

//=====================================  备份 与 恢复 =================================================================
1、MongoDB数据备份
mongodump命令脚本语法如下:
mongodump -h dbhost -d dbname -o dbdirectory

-h:
//MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:
//需要备份的数据库实例,例如:test
-o:
//备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

实例
//在本地使用 27017 启动你的mongod服务。打开命令提示符窗口,进入MongoDB安装目录的bin目录输入命令mongodump:
>mongodump
//执行以上命令后,客户端会连接到ip为 127.0.0.1 端口号为 27017 的MongoDB服务上,并备份所有数据到 bin/dump/ 目录中。命令输出结果如下:

mongodump 命令可选参数列表如下所示:

语法	                                             描述	                           实例
mongodump --host HOST_NAME --port PORT_NUMBER	     该命令将备份所有MongoDB数据	   mongodump --host runoob.com --port 27017
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY		                               mongodump --dbpath /data/db/ --out /data/backup/
mongodump --collection COLLECTION --db DB_NAME	   该命令将备份指定数据库的集合。	 mongodump --collection mycol --db test

2、MongoDB数据恢复
mongodb使用 mongorestore 命令来恢复备份的数据。
语法
mongorestore命令脚本语法如下:
>mongorestore -h <hostname><:port> -d dbname <path>

--host <:port>, -h <:port>:
	//MongoDB所在服务器地址,默认为: localhost:27017
--db , -d :
	//需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
--drop:
	//恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
<path>:
	//mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。
	//你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录。
--dir:
  //指定备份的目录
  //你不能同时指定 <path> 和 --dir 选项。

接下来我们执行以下命令:
>mongorestore

//=====================================  MongoDB 监控 =================================================================

mongostat 命令    //间隔固定时间获取mongodb的当前运行状态.

mongotop 命令			//查看哪些大量的时间花费在读取和写入数据.


3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
11111111111111111111111111111111111111111111-以下为高级教程-1111111111111111111111111111111111111111111111111111111
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

//=====================================  MongoDB 关系 =================================================================
1、首先几对几的关系都有
2、嵌入式关系  例如 地址嵌入到用户信息中
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
} 
3、引用式关系 通过引用文档的 id 字段来建立关系 
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}
//以上实例中,用户文档的 address_ids 字段包含用户地址的对象id(ObjectId)数组。
//我们可以读取这些用户地址的对象id(ObjectId)来获取用户的详细地址信息。
//这种方法需要两次查询,第一次查询用户地址的对象id(ObjectId),第二次通过查询的id获取用户的详细地址信息。
//=====================================  MongoDB 数据库引用 =================================================================

MongoDB 引用有两种:

手动引用(Manual References)
DBRefs

DBRef的形式:
{ $ref : , $id : , $db :  }
三个字段表示的意义为:
	//$ref:集合名称
	//$id:引用的id
	//$db:数据库名称,可选参数
以下实例中用户数据文档使用了 DBRef, 字段 address:
{
   "_id":ObjectId("53402597d852426020000002"),
   "address": {
   "$ref": "address_home",
   "$id": ObjectId("534009e4d852427820000002"),
   "$db": "runoob"},
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin"
}
//address DBRef 字段指定了引用的地址文档是在 runoob 数据库下的 address_home 集合,id 为 534009e4d852427820000002。

//以下代码中,我们通过指定 $ref 参数(address_home 集合)来查找集合中指定id的用户地址信息:
var user = db.users.findOne({"name":"Tom Benzamin"})
var dbRef = user.address
db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
以上实例返回了 address_home 集合中的地址数据:
{
   "_id" : ObjectId("534009e4d852427820000002"),
   "building" : "22 A, Indiana Apt",
   "pincode" : 123456,
   "city" : "Los Angeles",
   "state" : "California"
}

//=====================================  MongoDB 覆盖索引查询 ============================================================
官方的MongoDB的文档中说明,覆盖查询是以下的查询:
//所有的查询字段是索引的一部分
//所有的查询返回字段在同一个索引中

//我们在 users 集合中创建联合索引,字段为 gender 和 user_name :
db.users.ensureIndex({gender:1,user_name:1})
//现在,该索引会覆盖以下查询:
db.users.find({gender:"M"},{user_name:1,_id:0})
//也就是说,对于上述查询,MongoDB的不会去数据库文件中查找。相反,它会从索引中提取数据,这是非常快速的数据查询。
//由于我们的索引中不包括 _id 字段,_id在查询中会默认返回,我们可以在MongoDB的查询结果集中排除它。
//下面的实例没有排除_id,查询就不会被覆盖:
db.users.find({gender:"M"},{user_name:1})

//最后,如果是以下的查询,不能使用覆盖索引查询:
//所有索引字段是一个数组
//所有索引字段是一个子文档

//=====================================  MongoDB 查询分析 =================================================================
MongoDB 查询分析可以确保我们所建立的索引是否有效,是查询语句性能分析的重要工具。
MongoDB 查询分析常用函数有:explain() 和 hint()。
//explain 例如
db.users.find({gender:"M"},{user_name:1,_id:0}).explain();//具体参数含义自行百度

//使用 hint 来强制 MongoDB 使用一个指定的索引
//如下查询实例指定了使用 gender 和 user_name 索引字段来查询:
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

//=====================================  MongoDB 原子性操作 =================================================================

//mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。
//但是mongodb提供了许多原子操作,比如文档的保存,修改,删除等,都是原子操作。
//所谓原子操作就是要么这个文档保存到Mongodb,要么没有保存到Mongodb,不会出现查询到的文档没有保存完整的情况。

使用 db.collection.findAndModify() 方法来判断书籍是否可结算并更新新的结算信息。
book = {
          _id: 123456789,
          title: "MongoDB: The Definitive Guide",
          author: [ "Kristina Chodorow", "Mike Dirolf" ],
          published_date: ISODate("2010-09-24"),
          pages: 216,
          language: "English",
          publisher_id: "oreilly",
          available: 3,
          checkout: [ { by: "joe", date: ISODate("2012-10-15") } ]
        }
db.books.findAndModify ({
   query: {
            _id: 123456789,
            available: { $gt: 0 }
          },
   update: {
             $inc: { available: -1 },
             $push: { checkout: { by: "abc", date: new Date() } }
           }
})
1原子操作常用命令
$set  	//用来指定一个键并更新键值,若键不存在并创建。
		{ $set : { field : value } }
$unset 	//用来删除一个键。
		{ $unset : { field : 1} }
$inc 		//$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
		{ $inc : { field : value } }
$push   //把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。
		{ $push : { field : value } }
$pushAll//同$push,只是一次可以追加多个值到一个数组字段内。
		{ $pushAll : { field : value_array } }
$pull 	//从数组field内删除一个等于value值。
		{ $pull : { field : _value } }
$addToSet//增加一个值到数组内,而且只有当这个值不在数组内才增加。

$pop 		//删除数组的第一个或最后一个元素
		{ $pop : { field : 1 } }
$rename //修改字段名称
		{ $rename : { old_field_name : new_field_name } }
$bit    //位操作,integer类型
		{$bit : { field : {and : 5}}}


//=====================================  MongoDB 高级索引 =================================================================
{
   "address": {
      "city": "Los Angeles",
      "state": "California",
      "pincode": "123"
   },
   "tags": [
      "music",
      "cricket",
      "blogs"
   ],
   "name": "Tom Benzamin"
}

1索引数组字段
//在数组中创建索引,需要对数组中的每个字段依次建立索引。
//所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。

//使用以下命令创建数组索引:
db.users.ensureIndex({"tags":1})
//创建索引后,我们可以这样检索集合的 tags 字段:
db.users.find({tags:"cricket"})
//为了验证我们使用使用了索引,可以使用 explain 命令:
db.users.find({tags:"cricket"}).explain()

2索引子文档字段
//假设我们需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。
//为子文档的三个字段创建索引,命令如下:
db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
//一旦创建索引,我们可以使用子文档的字段来检索数据:
db.users.find({"address.city":"Los Angeles"})   
//查询表达不一定遵循指定的索引的顺序,mongodb 会自动优化。所以上面创建的索引将支持以下查询: 换句话就是不是最左原则
db.users.find({"address.state":"California","address.city":"Los Angeles"}) 
//同样支持以下查询:
db.users.find({"address.city":"Los Angeles","address.state":"California","address.pincode":"123"})

//=====================================  MongoDB 索引限制 =================================================================
内存(RAM)使用
//由于索引是存储在内存(RAM)中,你应该确保该索引的大小不超过内存的限制。
//如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
查询限制
//索引不能被以下的查询使用:
//正则表达式及非操作符,如 $nin, $not, 等。
//算术运算符,如 $mod, 等。
//$where 子句
//所以,检测你的语句是否使用索引是一个好的习惯,可以用explain来查看。

索引键限制
//从2.6版本开始,如果现有的索引字段的值超过索引键的限制,MongoDB中不会创建索引。

插入文档超过索引键限制
//如果文档的索引字段值超过了索引键的限制,MongoDB不会将任何文档转换成索引的集合。与mongorestore和mongoimport工具类似。

最大范围
//集合中索引不能超过64个
//索引名的长度不能超过128个字符
//一个复合索引最多可以有31个字段

//=====================================  MongoDB ObjectId =================================================================
ObjectId 是一个12字节 BSON 类型数据,有以下格式:
//前4个字节表示时间戳
//接下来的3个字节是机器标识码
//紧接的两个字节由进程id组成(PID)
//最后三个字节是随机数。
1创建新的ObjectId
newObjectId = ObjectId();   //固有函数生成
//你也可以使用生成的id来取代MongoDB自动生成的ObjectId:
myObjectId = ObjectId("5349b4ddd2781d08c09890f4");

2创建文档的时间戳
//由于 ObjectId 中存储了 4 个字节的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:
ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()

3ObjectId转换为字符串
//在某些情况下,您可能需要将ObjectId转换为字符串格式。你可以使用下面的代码:
new ObjectId().str

//=====================================  MongoDB Map Reduce =================================================================
//Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。
//MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用。
//以下是MapReduce的基本语法:
>db.collection.mapReduce(
   function() {emit(key,value);},  //map函数
   function(key,values) {return reduceFunction},   //reduce 函数
   {
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)
//Map函数调用emit(key,value)遍历一个或多个集合中所有的记录,进行分组(group by),然后将key与value传给Reduce函数进行处理,输出结果
//Map 函数必须调用 emit(key, value) 返回键值对。

1参数说明:
//map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
//reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组变成一个单一的值value。。
//out 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
//query 一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
//sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
//limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)

2样例:如下
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "mark",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "mark",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "runoob",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "runoob",
   "status":"disabled"
})
WriteResult({ "nInserted" : 1 })
>db.posts.insert({
   "post_text": "菜鸟教程,最全的技术文档。",
   "user_name": "runoob",
   "status":"active"
})
WriteResult({ "nInserted" : 1 })

//现在,我们将在 posts 集合中使用 mapReduce 函数来选取已发布的文章(status:"active"),
//并通过user_name分组,计算每个用户的文章数:
db.posts.mapReduce( 
   function() { emit(this.user_name,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
)
//以上 mapReduce 输出结果为:
{
        "result" : "post_total",
        "timeMillis" : 23,
        "counts" : {
                "input" : 5,
                "emit" : 5,
                "reduce" : 1,
                "output" : 2
        },
        "ok" : 1
}
//结果表明,共有 5 个符合查询条件(status:"active")的文档, 
//在map函数中生成了 5 个键值对文档,最后使用reduce函数将相同的键值分为 2 组。

具体参数说明:
//result:		储存结果的collection的名字,这是个临时集合,MapReduce的连接关闭后自动就被删除了。
//timeMillis:执行花费的时间,毫秒为单位
//input:			满足条件被发送到map函数的文档个数
//emit:			在map函数中emit被调用的次数,也就是所有集合中的数据总量
//ouput:			结果集合中的文档个数(counts对调试非常有帮助)
//ok:				是否成功,成功为1
//err:				如果失败,这里可以有失败原因,不过从经验上来看,原因比较模糊,作用不大
使用 find 操作符来查看 mapReduce 的查询结果:
>db.posts.mapReduce( 
   function() { emit(this.user_name,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
).find()

以上查询显示如下结果:
{ "_id" : "mark", "value" : 4 }
{ "_id" : "runoob", "value" : 1 }

//用类似的方式,MapReduce可以被用来构建大型复杂的聚合查询。
//Map函数和Reduce函数可以使用 JavaScript 来实现,使得MapReduce的使用非常灵活和强大。

//=====================================  MongoDB 全文检索 =================================================================
//全文检索对每一个词建立一个索引,指明该词在文章中出现的次数和位置,
//当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。
这个过程类似于通过字典中的检索字表查字的过程。

1启用全文检索
//MongoDB 在 2.6 版本以后是默认开启全文检索的,如果你使用之前的版本,你需要使用以下代码来启用全文检索:
db.adminCommand({setParameter:true,textSearchEnabled:true})
//或者使用命令:
mongod --setParameter textSearchEnabled=true
2创建全文索引
//考虑以下 posts 集合的文档数据,包含了文章内容(post_text)及标签(tags):
{
   "post_text": "enjoy the mongodb articles on Runoob",
   "tags": [
      "mongodb",
      "runoob"
   ]
}
//我们可以对 post_text 字段建立全文索引,这样我们可以搜索文章内的内容:
db.posts.ensureIndex({post_text:"text"})
3使用全文索引
//现在我们已经对 post_text 建立了全文索引,我们可以搜索文章中的关键词 runoob:
db.posts.find({$text:{$search:"runoob"}})
//以下命令返回了如下包含 runoob 关键词的文档数据:
{ 
   "_id" : ObjectId("53493d14d852429c10000002"), 
   "post_text" : "enjoy the mongodb articles on Runoob", 
   "tags" : [ "mongodb", "runoob" ]
}
//如果你使用的是旧版本的 MongoDB,你可以使用以下命令:
db.posts.runCommand("text",{search:"runoob"})
4删除全文索引
//删除已存在的全文索引,可以使用 find 命令查找索引名:
db.posts.getIndexes()
//通过以上命令获取索引名,本例的索引名为post_text_text,执行以下命令来删除索引:
db.posts.dropIndex("post_text_text")

//=====================================  MongoDB 正则表达式 =================================================================
//MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。
//MongoDB使用PCRE (Perl Compatible Regular Expression) 作为正则表达式语言。
//不同于全文检索,我们使用正则表达式不需要做任何配置。
//考虑以下 posts 集合的文档结构,该文档包含了文章内容和标签:
{
   "post_text": "enjoy the mongodb articles on runoob",
   "tags": [
      "mongodb",
      "runoob"
   ]
}
//使用正则表达式
1以下命令使用正则表达式查找包含 runoob 字符串的文章:
db.posts.find({post_text:{$regex:"runoob"}})
//以上查询也可以写为:
db.posts.find({post_text:/runoob/})
2不区分大小写的正则表达式
//如果检索需要不区分大小写,我们可以设置 $options 为 $i。
//以下命令将查找不区分大小写的字符串 runoob:
db.posts.find({post_text:{$regex:"runoob",$options:"$i"}})
//集合中会返回所有包含字符串 runoob 的数据,且不区分大小写:
{
   "_id" : ObjectId("53493d37d852429c10000004"),
   "post_text" : "hey! this is my post on  runoob", 
   "tags" : [ "runoob" ]
} 
3数组元素使用正则表达式
//我们还可以在数组字段中使用正则表达式来查找内容。 这在标签的实现上非常有用,
//如果你需要查找包含以 run 开头的标签数据(ru 或 run 或 runoob), 你可以使用以下代码:
db.posts.find({tags:{$regex:"run"}})
4优化正则表达式查询
//如果你的文档中字段设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查询速度更快。
//如果正则表达式是前缀表达式,所有匹配的数据将以指定的前缀字符串为开始。
//例如: 如果正则表达式为 ^tut ,查询语句将查找以 tut 为开头的字符串。
//这里面使用正则表达式有两点需要注意:
//正则表达式中使用变量。一定要使用eval将组合的字符串进行转换,不能直接将字符串拼接后传入给表达式。否则没有报错信息,只是结果为空!
//实例如下:
//以下是模糊查询包含title关键词, 且不区分大小写:
title:eval("/"+title+"/i")    // 等同于 title:{$regex:title,$Option:"$i"}   

//=====================================  MongoDB GridFS =================================================================
//GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等)。
//GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。
//GridFS 可以更好的存储大于16M的文件。
//GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。
//GridFS 用两个集合来存储一个文件:fs.files与fs.chunks。
//每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据(filename,content_type,还有用户自定义的属性)将会被存在files集合中。
//以下是简单的 fs.files 集合文档:
{
   "filename": "test.txt",
   "chunkSize": NumberInt(261120),
   "uploadDate": ISODate("2014-04-13T11:32:33.557Z"),
   "md5": "7b762939321e146569b07f72c62cca4f",
   "length": NumberInt(646)
}
//以下是简单的 fs.chunks 集合文档:
{
   "files_id": ObjectId("534a75d19f54bfec8a2fe44b"),
   "n": NumberInt(0),
   "data": "Mongo Binary Data"
}
//GridFS 添加文件
//现在我们使用 GridFS 的 put 命令来存储 mp3 文件。 调用 MongoDB 安装目录下bin的 mongofiles.exe工具。
//打开命令提示符,进入到MongoDB的安装目录的bin目录中,找到mongofiles.exe,并输入下面的代码:
mongofiles.exe -d gridfs put song.mp3
//GridFS 是存储文件的数据名称。如果不存在该数据库,MongoDB会自动创建。Song.mp3 是音频文件名。
//使用以下命令来查看数据库中文件的文档:
db.fs.files.find()
//以上命令执行后返回以下文档数据:
{
   _id: ObjectId('534a811bf8b4aa4d33fdf94d'), 
   filename: "song.mp3", 
   chunkSize: 261120, 
   uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
   length: 10401959 
}
//我们可以看到 fs.chunks 集合中所有的区块,以下我们得到了文件的 _id 值,我们可以根据这个 _id 获取区块(chunk)的数据:
db.fs.chunks.find({files_id:ObjectId('534a811bf8b4aa4d33fdf94d')})
//以上实例中,查询返回了 40 个文档的数据,意味着mp3文件被存储在40个区块中。

//=====================================  MongoDB 固定集合(Capped Collections) =================================================================
//MongoDB 固定集合(Capped Collections)是性能出色且有着固定大小的集合,
//对于大小固定,我们可以想象其就像一个环形队列,当集合空间用完后,再插入的元素就会覆盖最初始的头部的元素!
1创建固定集合
//我们通过createCollection来创建一个固定集合,且capped选项设置为true:
db.createCollection("cappedLogCollection",{capped:true,size:10000})
//还可以指定文档个数,加上max:1000属性:
db.createCollection("cappedLogCollection",{capped:true,size:10000,max:1000})
1判断集合是否为固定集合:
db.cappedLogCollection.isCapped()
1如果需要将已存在的集合转换为固定集合可以使用以下命令:
db.runCommand({"convertToCapped":"posts",size:10000})
//以上代码将我们已存在的 posts 集合转换为固定集合。
1固定集合查询
//固定集合文档按照插入顺序储存的,默认情况下查询就是按照插入顺序返回的,也可以使用$natural调整返回顺序。
db.cappedLogCollection.find().sort({$natural:-1})
1固定集合的功能特点
//可以插入及更新,但更新不能超出collection的大小,否则更新失败,不允许删除,但是可以调用drop()删除集合中的所有行,但是drop后需要显式地重建集合。
//在32位机子上一个cappped collection的最大值约为482.5M,64位上只受系统文件大小的限制。
1固定集合属性及用法
属性
//属性1:对固定集合进行插入速度极快
//属性2:按照插入顺序的查询输出速度极快
//属性3:能够在插入最新数据时,淘汰最早的数据
用法
//用法1:储存日志信息
//用法2:缓存一些少量的文档


//=====================================  MongoDB 自动增长(自定义自动整增长列) =================================================================
//MongoDB 没有像 SQL 一样有自动增长的功能, MongoDB 的 _id 是系统自动生成的12字节唯一标识。
//但在某些情况下,我们可能需要实现 ObjectId 自动增长功能。
//由于 MongoDB 没有实现这个功能,我们可以通过编程的方式来实现,以下我们将在 counters 集合中实现_id字段自动增长。

1使用counters集合
//考虑以下 products 文档。我们希望 _id 字段实现 从 1,2,3,4 到 n 的自动增长功能。
{
  "_id":1,
  "product_name": "Apple iPhone",
  "category": "mobiles"
}
//为此,创建 counters 集合,序列字段值可以实现自动长:
db.createCollection("counters");
//现在我们向 counters 集合中插入以下文档,使用 productid 作为 key:
//sequence_value 字段是序列通过自动增长后的一个值。 
//使用以下命令插入 counters 集合的序列文档中:
db.counters.insert({_id:"productid",sequence_value:0});
2创建Javascript函数
//现在,我们创建函数 getNextSequenceValue 来作为序列名的输入, 
//指定的序列会自动增长 1 并返回最新序列值。在本文的实例中序列名为 productid 。

function getNextSequenceValue(sequenceName){
   var sequenceDocument = db.counters.findAndModify(
      {
         query:{_id: sequenceName },
         update: {$inc:{sequence_value:1}},
         "new":true
      });
   return sequenceDocument.sequence_value;
}
3使用Javascript函数
//接下来我们将使用 getNextSequenceValue 函数创建一个新的文档, 并设置文档 _id 自动为返回的序列值:
db.products.insert({
   "_id":getNextSequenceValue("productid"),
   "product_name":"Apple iPhone",
   "category":"mobiles"});
db.products.insert({
   "_id":getNextSequenceValue("productid"),
   "product_name":"Samsung S3",
   "category":"mobiles"});

//就如你所看到的,我们使用 getNextSequenceValue 函数来设置 _id 字段。
//为了验证函数是否有效,我们可以使用以下命令读取文档:
db.products.find();





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值