• mongoDB高级查询与索引


    整理来自

    https://www.shiyanlou.com/courses/running/78

    覆盖索引查询

    所有的查询字段都是索引的一部分;所有的查询返回字段在同一个索引中。

    由于索引存在于RAM中,因而从索引中获取数据要比扫面文档更快

    范例:创建如下users集合(使用前面所学的方法创建该集合):

    {
       "contact": "987654321",
       "dob": "01-01-1991",
       "gender": "M",
       "name": "Tom Benzamin",
       "user_name": "tombenzamin"
    }
    

    在user中创建一个联合索引

    > db.users.ensureIndex({gender:1,user_name:1})
    

    该索引会覆盖下面的查询:

    > db.users.find({gender:"M"},{user_name:1,_id:0})
    

    对于上述查询,MongoDB不会在数据库文件中查找,而会从索引中提取数据。因为索引中不包含_id字段,所以_id在查询中会默认返回,可以在查询结果中将其排除。而db.users.find({gender:"M"},{user_name:1})就不会被索引覆盖

    高级索引

    创建如下users集合(使用前面所学的方法创建该集合):

    {
       "address": {
          "city": "chengdu",
          "province": "sichuan",
          "pincode": "123"
       },
       "tags": [
          "music",
          "cricket",
          "blogs"
       ],
       "name": "clound"
    }
    

    索引数组字段,在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 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":"chengdu","address.province":"sichuan"})
    

    同样支持以下查询:

    > db.users.find({"address.city":"chengdu","address.province":"sichuan","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()
  • 相关阅读:
    我说
    时间管理
    职场自我管理
    html元素不可见的三种方式
    windows查看端口占用情况
    windows下vbs脚本隐藏控制台
    找钥匙问题
    CSS中的偏僻知识点
    竖式谜题
    node库的选择
  • 原文地址:https://www.cnblogs.com/wind90/p/4606075.html
Copyright © 2020-2023  润新知