• 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

  • 相关阅读:
    datagridview 数据刷新 从新绑定
    SVN 出现This client is too old to work with working copy...错误
    【转】ASPX和HTML获取系统根目录的路径
    C#程序最小化到托盘图标
    Winform的html编辑控件htmleditor 有时候无法为里面HTML属性初始化
    C# HttpWebRequest保存cookies模拟登录的方法【z】【解决】
    快速生成解决方案 ctrl + shilf + b
    datagridview只允许单选
    数据库int类型 才可以自增长
    C# dataTable实用例
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9980143.html
Copyright © 2020-2023  润新知