• Mongo索引学习笔记


    索引使用场景

    优:加快查询速度

    劣:增删改会产生额外的开销、占用空间

    tips: 返回集合中一半以上的数据,全表扫描的效率高

    索引基础

    基础操作

    查看索引:db.test.getIndexes()

    创建索引:db.test.ensureIndex({"username":1},{"background":true,"name":"index_test_name"}) //已有大量数据时可后台执行不阻塞

    删除索引: db.test.dropIndex({"username":1})

    查看索引大小: db.test.totalIndexSize()

    属性

    索引顺序:

    1为正序,-1为逆序

    在复合索引中需注意顺序(id:1, age:-1)

    索引属性:

    唯一性

    
    db.test.ensureIndex({x:1,y:1},{unique:true})
    

    稀疏性

    
    db.test.ensureIndexx({},{sparse:true/false})
    不稀疏(默认):
    1. 可插入不存在索引字段的数据,null; 
    2. 可筛选不存在字段: db.test.find({m:{$exist:ture}})
    稀疏:
    

    优化分析方法

    explain

    获知系统如何处理请求

    
    cursor  返回游标类型(BasicCursor或BtreeCursor)
    nscanned  被扫描的文档数量
    n 返回的文档数
    millis  耗时(毫秒)
    indexBounds  所使用的索引
    

    hint

    强制使用某个索引

    
    db.test.find({"age":20}).hint({"name":1,"age":1}) // .hint(name_1_age_1)
    

    profile

    设置日志级别,记录慢查询

    Tips

    1. 查询条件顺序自动调整
    2. 能为前缀式的正则表达式命中索引(/^z/)
    3. 对需要大量sort的键建立索引,避免全部数据加载到内存
    4. $ne、$nin 不会使用索引

    索引种类

    _id索引

    默认生成唯一字段

    单键索引

    值为一个单一的值

    
    db.test.ensureIndex({x:1})
    

    多键索引

    值具有多个记录,如数组、内嵌文档

    
    db.test.insert({x:[1,2,3,4]})
    

    每一个索引字段最多包含一个数组

    
    Y: {_id:1, a:[1,2], b:1, category:"A array"} 与 {_id:2, a:1, b:[1,2], category:"B array"}
    N: {_id:3, a:[1,2], b:[1,2], category:"AB both array"}
    

    查询

    
    //数组查询
    数组中包含: db.fruitshop.find({"fruits":"apple"})
    包含多个: db.fruitshop.find({"fruits":{"$all":["apple", "banana"]}})
    精确匹配: db.fruitshop.find({"fruits":["apple","orange","pear"]}) //顺序与数量一致
    特定位置元素查询: db.fruitshop.find({"fruits.1":"orange"})
    查询数组长度: db.fruitshop.find({"fruits":{"$size":3}}) //size不能和其他操作符连用,如'$gt'等
    返回固定长度: db.fruitshop.find({"fruits":{"$slice":2}}) //前2个
                  db.fruitshop.find({"fruits":{"$slice":-1}}) //后1个
                  db.fruitshop.find({"fruits":{"$slice":[3,6]}}) //第4~7个,无数据则返回[]
    
    //内嵌文档
    完全匹配: db.staff.find({"name":{"first":"joe","middle":"bush"}}) //顺序与数量一致
    键值对查询: db.staff.find({"name.first":"joe","name.middle":"bush"}) //点表示法,在插入时键名不能包含点(约束)
    多层内嵌: elemMatch  db.blogs.find({"comment":{"$elemMatch":{"author":"joe", "score":{"$gte":3}}}}) //内嵌文档中匹配author和score条件
              where  db.fruitshop.find({"$where":function(){}}) //性能低,每个文档转换成一个javascript对象放入函数执行
    
    

    复合索引

    多个条件,从左到右执行

    
    {a:1,b:1,c:1} => {a:1},{a:1,b:1},{a:1,b:1,c:1}
    
    db.test.ensureIndex({x:1,y:1})
    

    过期索引

    一段时间后过期,删除相应数据(用户的登录信息、存储的日志)

    
    db.test.ensureIndex({time:1},{expireAfterSeconds:30})
    

    限制

    字段类型必须是ISODate或者ISODate数组(数组中最小的时间)
    不能是复合索引(不能指定两个过期时间)
    删除时间不精确(后台进程60s跑一次)

    全文索引

    字符串或者字符串数组可搜索

    
    //建立索引
    db.test.ensureIndex({title:"text"})
    db.test.ensureIndex({key1:"text",key2:"text"}) //对多个字段创建全文索引
    db.test.ensureIndex({$**:"text"}) //对所有字段建全文索引
    
    //查找
    不需要指定字段名称: db.test.find({"$text":{"$search":"coffee"}}) //每个数据集合只允许创建一个全文索引(可针对一个、多个、全部字段)
    查找多个关键词(空格代表 或 操作): db.test.find({"$text":{"$search":"aa bb cc"}})
    指定不包含词(-代表 非 操作): db.test.find({"$text":{"$search":"aa bb -cc"}})
    与关系操作: db.test.find({"$text":{"$search":""aa" "bb" "cc""}})
    相似度查询: db.test.find({"$text":{"$search":"aa bb"}},{"score:{"$meta":"textScore"}"}) //score字段得分越高,相关度越高
                db.test.find({"$text":{"$search":"aa bb"}},{"score":{"$meta":"textScore"}}).sort({"score":{"$meta":"textScore"}}) //score相关度排序
                
    //限制
    每次查询只能指定一个$text
    有了$text则hint(强制指定索引)不起作用
    中文支持不好(企业版可支持)
    
    

    地理位置索引

    将点的位置存储,可以按位置查找其他点

    2D索引
    用于存储和查找平面上的点

    
    db.test.ensureIndex({w:"2d"})
    
    //使用经纬度表示
    取值范围 经度[-180,180] 纬度[-90,90]
    db.test.insert({w:[180,90]})
    
    //查询
    使用$near查询距离某个点最近的点(默认返回100个)
        db.test.find({"$near":[x,y]})
        db.test.find({w:{"$near":[x,y],"$maxDistance":"z"}}) //限制返回的最远距离
     
    使用$geoWithin查询某个形状内的点
        矩形($box:[[x1,y1],[x2,y2]]) db.test.find({w:{"$geoWithin:{"$box":[[0,0],[3,3]]}}"}})
        圆形($center:[[x,y],r])  db.test.find({w:{"$geoWithin":{"$center":[0,0],5}}})
        多边形($polygon:[[x1,y1],[x2,y2],..)  db.test.find({w:{"$geoWithin":{"$polygon":[[0,0],[0,1],[2,5],[6,1]]}}})
        
    使用$geoNear查询,返回最大距离和平均距离等数据
    
    

    相关扩展:
    《地理位置索引的实现原理》

    2Dsphere索引
    用于存储和查找球面上的点

    
    db.test.ensureIndex({key:"2dsphere"})
    

    原文地址:https://segmentfault.com/a/1190000015567585

  • 相关阅读:
    MVP模式与MVVM模式
    webpack的配置处理
    leetcode 287 Find the Duplicate Number
    leetcode 152 Maximum Product Subarray
    leetcode 76 Minimum Window Substring
    感知器算法初探
    leetcode 179 Largest Number
    leetcode 33 Search in Rotated Sorted Array
    leetcode 334 Increasing Triplet Subsequence
    朴素贝叶斯分类器初探
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9980143.html
Copyright © 2020-2023  润新知