入门

1.1 文档

多个键及其关联的值有序的放在一起便是文档,类似于关系型数据库中的行,以json的样子展现 注:1.文档中的键是有序的。 2.值可以是各种不同的类型 3.区分大小写 4.不能有重复的键

1.2 集合与子集合

**集合:**集合是一组文档,类似于关系型数据库的表 子集合用.字符分开的按命名空间的子集合,如blog.posts和blog.authors,目的使让组织结构更好,其实父子集合没有任何关系

1.3 数据库

数据库由多个集合组成,一个mongoDB实例承载多个数据库,每个数据库有独立的权限. eg:cms.blog.posts

1.4 mongodb运行

./mongod 启动mongo,./mongo 客户端,是一个javascript shell

1.5: mongodb 基本操作

do.blog.find() 查找    db.blog.insert(post)插入  post={"title":"aa"} 赋值
db.blog.findOne()查找一个文档
db.blog.update({"title":"aa"},post) 更新
db.blog.remove()删除文档

1.6:数据类型

ObjectId() 12字节的唯一ID, 文档可以包含javascript代码:{x:function{…}},也可以包含数组[1,2,3,4],文档中也可以包含文档

创建,更新以及删除文档

2.1修改器

"$set" 用来指定一个键的值,如果键不存在,则创建它 {"$set":{"favorite book":"war and peace"}}  
"$unset"将键完全删除   
"$inc"用来修改已有键的值 db.games.update({"game":"pinball","user":"joe},{"$inc":{"scope":50}})
$push:往数组中加入一个元素,如果不存在该数组,则创建一个
$addToSet 能避免重复
$pull:删除第一个
comments.$.author 表示已经查询到的作者

2.2 upinsert和 save

upinsert: 是一种特殊的更新,要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新的文档.如果找到了匹配的文档,则正常更新.(update最后一个参数为true,则为upinsert)
save: 可以再文档不存在时插入,存在时更新。它只有一个参数:文档。要是这个文档含有"_id"键,save会调用upsert。否则,会调用插入。

默认情况下,更新只能对符合条件的第一个文档执行操作。要是多个文档符合条件,其余的文档没有变化。要使所有的匹配到的文档都得到更新,可以设置Update的第四个参数为true。 getLastError:查看更新了多少个文档. findAndModify:返回更新的文档

find查询

3.1 基础查询

  • 只要查询username和email:db.users.find({}, {“username”:1, “email”:1})
  • 不希望有username: db.users.find({}, “username”:0)
  • $lt, $lte, $gt, $gte,$ne 分别对应 <, <=, >, >=,!=操作符 eg:{“index”:{"$gt":new Date(“01/01/2007”)}}
  • $in db.users.find(age,{"$in",[10,11,12]})
  • $or db.users.find("$or", [{“age”:10}, {“name”:“aaa”}])
  • $not db.users.find(“id_num”:{"$not":{"$mod":[5,1]}})
  • $exists:db.users.find()

3.2 查询数组

  • 数组中的每个元素都是键的值
  • $all 需要通过多个元素来匹配数组 db.food.find({“fruit”:{$all : [“apple”, “banana”]}}),顺序无关紧要,如果经过精确匹配,就要求顺序
  • $size 可以查询到符合元素个数的文档
  • $slice用来返回数组的一个子集合,用于find的第二个参数 $slice:10前10条评论, $slice:-10 后10条评论, $slice:[23, 10]返回24~33条记录,slice不特别说明的话,会默认返回所有的键

3.3 查询内嵌文档

查询内嵌文档可以用点来表示层级结构,加点以后,就与顺序无关了,不加点,查询内嵌文档需要与整个内嵌文档相匹配

3.4 $eleMatch

将限定条件进行分组,仅当需要对一个内嵌文档的多个键操作时才会起作用

3.5 $where

$where 能提供一个javascript来作为查询的条件
eg 如果一个文档中的一个键的值和另一键的值相等,则返回
           db.foo.find({$where:function(){
                    for(var current in this){
                          for(var other in this){
                               if(current != other && this[current] == this[other]){return true;}
                          }
                    }
           }});
也可以用一个表达式来作为条件
db.foo.find({$where: function(){return this.x + this.y == 10;}})

注:不是非常必要,一定要避免使用$where查询,因为速度上会比普通查询慢很多

3.6 游标

使用eg:
var cursor=db.collection.find();
	while(cursor.hasNext()) {
	    obj = cursor.next();
	};
	cursor.forEach(function(x){});

3.7 limit, skip和sort

limit上限,skip跳过 sort 参数是一组键值对,db.c.find().sort({username:1,age:-1}) , 1是升序, -1是降序,三个方法可以组合使用,注:避免使用skip略过大量的结果,分页的另外一种方法:

	var page1 = db.foo.find().sort({"date":-1}).limit(100)
  var lastest = null;
  while(page1.hasNext()) {
       lastest = page1.next();
			 display(lastest);
  }
  var page2 = db.foo.find({"date":{"$gt":latest.date}})
  page2.sort({"date":-1}).limit(100);

索引

  1. ensureIndex创建索引, 创建索引只对查询该键的速度有帮助,对于其他键没有帮助,即使包含了该键,所以应该对所有要查询的键创建索引 eg:db.ensureIndex({username:1})
  2. 索引会造成插入,更新等操作造成额外的开销
  3. ensureIndex第二个参数为索引命名
  4. 唯一索引:db.people.ensureIndex({“username”:1},{“unique”,true})
  5. 消除重复: db.people.ensureIndex({username,1},{“unique”:true,“dropDups”:true})
  6. 复合唯一索引:单个建可以相同,只要所有键的组合起来不同就行
  7. .explain()会出现更多查询的信息, hint严格使用某个索引
  8. 索引的元信息存储在每个数据库的system.indexes集合中,这是一个保留集合
  9. {background:true} 可以使建立索引在后台进行
  10. dropIndexes:删除索引
  11. 地理空间索引: eg:db.map.ensureIndex({“gps”:2d}); gps键必须是某种形式的一对值: {“gps”:[0,100]},键名是可以随意的, db.star.trek.ensureIndex({“light-years”:“2d”},{“min”:-1000, “max”:1000}); 然后使用find来查询 db.map.find({“gps”:{"$near":[40, -73]}})这会按照[40,74]由近到远的方式将map集合的所有文档都返回

聚合

  1. count:查询文档数量
  2. distinct:用来找出给定键的所有不同的值,使用时必须指定集合和键 db.runCommand({“distinct”:“people”,“key”:“age”})
  3. eg 查看股市30天内每天的收盘价: db.runCommand({group:{ ns:“stocks”, //集合 key:“day”, //键 initial:{“time”:0}, //每一组reduce函数调用的时间 $reduce:function(doc,prev){ if(doc.time>prev.time){ prev.price = doc.price;prev.time=doc.time; (doc当前文档, prev累加文档) } }
    }}) 4.精简器:finalizer用于精简传到用户的数据; 5.$keyf:能依据各种复杂的条件进行分组 6.mapReduce:

暂时学习到这里,比较粗略的学习了一些语法与概念,后续有详细使用和学习,再继续更新