Mongodb数据库(2)

上一篇了解了Mongodb基本常识,下面继续:

一、查询语句:

  • find() 用法: 查询数据,不加任何参数默认返回所有数据记录
    db.COLLECTION_NAME.find()
  • pretty() :可以使查询输出的结果更美观。
    db.post.find().pretty()
  • AND:当 find() 中传入多个键值对时,MongoDB就会将其作为 AND 查询处理。db.mycol.find({ key1: value1, key2: value2 }).pretty()
  • OR:以 $or 作为关键词;
    $or:[
        {"by":"wangwu"},
        {"title": "Mongodb}
    ]
}).pretty()```
- 同时使用AND 和OR

db.post.find({
“likes”: {$gt:10},
$or: [
{“name”: “wangwu”},
{“title”: “Mongodb数据库(2)”}
]
}).pretty()

#####{\$gt:10} 表示大于10,\$lt 表示小于,\$lte 表示小于等于,\$gte 表示大于等于,\$ne 表示不等于
条件操作符:
(>) 大于 - \$gt #greate
(<) 小于 - \$lt #low
(>=) 大于等于 - \$gte #equal
(<= ) 小于等于 - \$lte

##二、更新和删除文档
- createCollection():创建集合

- db.COLLECTION.drop():删除集合

- db.COLLECTION_NAME.insert(document):插入文档

userdoc1=({“user_id”:1,”name”:”cloud”,”state”:”active”,”actor”:”user”,”e-mail”:”test@qq.com“,”VM_num”:2,”time”:[{“date”:”2014-08-12″,”hour”:”10:53 PM”}] })
userdoc2=({“user_id”:2,”name”:”testadmin”,”state”:”active”,”actor”:”admin”,”e-mail”:”test@qq.com“,”VM_num”:2,”time”:[{“date”:”2014-08-11″,”hour”:”06:34 AM”}] })
doc1=({“name”:”peter”,”position”:”teacher”}) #先定义文档

db.mongodbtest.insert(userdoc1)
db.mongodbtest.insert(userdoc1)


- db.COLLECTION_NAME.update(SELECTION_CRITERIA,UPDATED_DATA):更新文档
```db.shiyanlou.update({"user_id":"02","e-mail":"test@qq.com"},{$set:{"e-mail":"wangwu@qq.com"}})```
将user_id=2的文档的e-mail改为wangwu @qq.com
第一个大括号内容标示查找条件,第二个大括号内容则表示更新后的数据
默认的update函数只对一个文档更新,如果想作用所有文档,则需要加入multi:ture
- db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA}):替换已存在的文档(和updata差不多,但updata更好用)

db.shiyanlou.save({“_id”:ObjectId(“53ea174ccb4c62646d9544f4″),”name”:”Bob”,”position”:”techer”})
WriteResult({“nMatched”:1,”nUpserted”:1,”nModified”:1})

- db.COLLECTION_NAME.remove(DELECTION_CRITERIA):删除文档
``db.mongodb.remove({"name":"Bob"})``
其实remove函数的参数跟update函数的第一个参数一样,相当于查找条件,注意,不要误删!

*删除后要用查找命令find确认数据,这是好的习惯

##三、查询、索引与聚合
- 条件操作符除了上面的大小等是第一种,第二种语法``type``
####type的值:
双精度型-1
字符串-2
对象-3
数组-4
二进制数据-5
对象ID-7
布尔类型-8
数据-9
空-10
正则表达式-11
JS代码-13
符号-14
有作用域的JS代码-15
32位整型数-16
时间戳-17
64位整型数-18
Min key-255
Max key-127
用法:``db.mongodbtest.find({"name":{$type:2}})``
- limit(读取指定数量的数据记录)与skip(读取时跳过指定数量的数据记录)
用法:``db.mongodbtest.find().limit(1).skip(1)``
- 排序:sort():升序用1,降序-1
用法:``db.mongodbtest.find().sort({"time":1})``

####索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库集合中一个文档或多个文档的值进行排序的一种结构。
用法:``db.mongodbtest.ensureIndex({"name":1})#同样1代表升序,-1代表降序
 ``

![ensureIndex()的可选参数](http://upload-images.jianshu.io/upload_images/744392-1f9b42d281656252.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

用法:``db.mongodbtest.ensureIndex({"user_id":1,"name":1},{background:1})``

####聚合

db.COLLECTION_NAME.aggregate({
$match:{x:1},
{limit:NUM},
$group:{_id:$age}
})

可选参数:
$match:查询,跟find一样;
$limit:限制显示结果数量;
$skip:忽略结果数量;
$sort:排序;
$group:按照给定表达式组合结果。
exp:``  db.mongodbtest.aggregate([{$group:{_id:"$name", user:{$sum:"$user_id"}}}])#$name意为取得name的值``

聚合表达式:
- $sum  计算总和
- $avg  计算平均值
- \$min和$max    计算最小和最大值
- $push 在结果文档中插入值到一个数组
- $addToSet 在结果文档中插入值到一个数组,但不创建副本
- $first    根据资源文档的排序获取第一个文档数据
- $last 根据资源文档的排序获取最后一个文档数据

####管道
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

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

db.mongodbtest.aggregate([{$match:{user_id:{$gt:0,$lte:2}}},{$group:{_id:”user”,count:{$sum:1}}}])
{“_id”:”user”,”count”:2}

##四、查询与索引进阶
所有的查询字段都是索引的一部分;所有的查询返回字段在同一个索引中。由于索引存在于RAM中,因而从索引中获取数据要比扫面文档更快
创建如下users集合:

{
“address”: {
“city”: “tianjin”,
“province”: “tianjin”,
“pincode”: “123”
},
“tags”: [
“music”,
“code”,
“blogs”
],
“name”: “yangxulei”
}“`
索引数组字段,在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。 范例:
> db.users.ensureIndex({"tags":1})
创建索引后,我们可以这样检索集合的 tags 字段:
> db.users.find({tags:"cricket"})
为了验证我们使用使用了索引,可以使用 explain 命令:
> db.users.find({tags:"cricket"}).explain()
以上命令执行结果中会显示 “cursor” : “BtreeCursor tags_1” ,则表示已经使用了索引。

  • 索引子文档字段
    假设需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。 范例: 为子文档的三个字段创建索引,命令如下:
    > db.users.ensureIndex({"address.city":1,"address.province":1,"address.pincode":1})
    一旦创建索引,我们可以使用子文档的字段来检索数据:
    > db.users.find({"address.city":"chengdu"})
    记住查询表达式必须遵循指定的索引的顺序。所以上面创建的索引将支持以下查询:
    > db.users.find({"address.city":"tianjin","address.province":"beijing"})
    同样支持以下查询:
    db.users.find({"address.city":"tianjin","address.province":"beijing","address.pincode":"123"})
  • 原子操作
    所谓原子操作,就是要么执行成功,要么执行失败,执行成功完成既定任务,执行失败还原执行前的状态。 常用原子操作命令:
    • $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}}}
  • explain()
    explain 操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。接下来我们在 users 集合中创建 gender 和 user_name 的索引:
> db.users.ensureIndex({gender:1,user_name:1})
> db.users.find({gender:"M"},{user_name:1,_id:0}).explain()```
结果中字段解释:
- indexOnly:为 true ,表示我们使用了索引;
- cursor:因为这个查询使用了索引,MongoDB中索引存储在B树结构中,所以这是也使用了BtreeCursor类型的游标。如果没有使用索引,游标的类型是- BasicCursor。这个键还会给出你所使用的索引的名称,你通过这个名称可以查看当前数据库下的system.indexes集合(系统自动创建)来得到索引的详细信息;
n:当前查询返回的文档数量;
- nscanned/nscannedObjects:表明当前这次查询一共扫描了集合中多少个文档,我们的目的是,让这个数值和返回文档的数量越接近越好;
- millis:当前查询所需时间,毫秒数;
- indexBounds:当前查询具体使用的索引。
- hint()

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hints来强迫MongoDB使用一个指定的索引。 通过这种方法在某些情形下会提升性能。 范例:指定使用 gender 和 user_name 索引字段来查询:

db.users.find({gender:”M”},{user_name:1,_id:0}).hint({gender:1,user_name:1})“`
可以使用 explain() 函数来分析以上查询:

> db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()```
    原文作者:多了去的YangXuLei
    原文地址: https://www.jianshu.com/p/dced3cec54dd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞