zoukankan      html  css  js  c++  java
  • mongodb的索引

    插入准备数据

    > for(var i=1;i<10;i++) { db.user2_collection.insert({name:i}) }
    WriteResult({ "nInserted" : 1 })
    > db.user2_collection.find()
    { "_id" : ObjectId("55f69331cc1593a1bb113958"), "name" : 1 }
    { "_id" : ObjectId("55f69331cc1593a1bb113959"), "name" : 2 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395a"), "name" : 3 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395b"), "name" : 4 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395c"), "name" : 5 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395d"), "name" : 6 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395e"), "name" : 7 }
    { "_id" : ObjectId("55f69331cc1593a1bb11395f"), "name" : 8 }
    { "_id" : ObjectId("55f69331cc1593a1bb113960"), "name" : 9 }

    一、索引的种类

    创建格式:db.集合名.ensureIndex({params},{params})

    其中第二个参数是索引的属性,如:名字{name:"索引名称"} 唯一性{unique:true/false} 稀疏性{sparse:true/false} 是否定时删除{expireAfterSeconds:秒数}

    唯一性是指创建了唯一索引的字段的值不能重复

    稀疏性是指一个集合中的每条文档的字段不是完全相同的,例如:在字段A上创建了{sparse:false}的索引,那么不管集合中的文档是否拥有字段A,mongodb都会维护索引

    1._id索引(主键索引吧) _id索引是绝大多数集合默认建立的唯一索引

    查看索引

    > db.user2_collection.getIndexes()
    [
            {
                    "v" : 1,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "test.user2_collection"
            }
    ]

    2.普通索引

    > db.user2_collection.insert({name:[1,2,3,4,5]})> db.user2_collection.ensureIndex({name:1},{name:"normal_index"}) //如果name的值是单个值,则mongodb会创建单键索引 如果是多个值则创建多键索引 1 表示asc排序 -1 表示desc排序
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    > db.user2_collection.getIndexes()
    [
            {
                    "v" : 1,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "test.user2_collection"
            },
            {
                    "v" : 1,
                    "key" : {
                            "name" : 1
                    },
                    "name" : "normal_index",
                    "ns" : "test.user2_collection"
            }
    ]

    3.复合索引 当我们的查询条件不是只有一个时,就需要建立复合索引 

    > db.user2_collection.ensureIndex({name:1,age:1})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 2,
            "numIndexesAfter" : 3,
            "ok" : 1
    }
    > db.user2_collection.getIndexes()
    [
            {
                    "v" : 1,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "test.user2_collection"
            },
            {
                    "v" : 1,
                    "key" : {
                            "name" : 1
                    },
                    "name" : "name_1",
                    "ns" : "test.user2_collection"
            },
            {
                    "v" : 1,
                    "key" : {
                            "name" : 1,
                            "age" : 1
                    },
                    "name" : "name_1_age_1",
                    "ns" : "test.user2_collection"
            }
    ]

    4.过期索引 在一段时间后会过期失效的索引 索引过期后相应的数据会被删除

    注意:

    a、存储过期索引字段的值必须是 ISODate 型 或  ISODate 数组型 否则数据不会被自动删除

    b、如果是数组型 则按最小的 ISODate 进行计算过期时间

    c、过期索引必须是普通索引(单键索引或多键索引)

    d、删除是由mongodb每60s跑一次的进程进行删除的,所以有一定的误差的,即过期时间到了,但是程序还没跑,那么数据也不会立即删除

    > db.user2_collection.insert({name:new Date(),hehe:1})
    
    > db.user2_collection.find()
    
    > db.user2_collection.ensureIndex({name:2},{expireAfterSeconds:10}) //创建一个十秒后过期的索引 
    
    > db.user2_collection.getIndexes()
    
    > db.user2_collection.insert({name:new Date(),hehe:2})
    
    > db.user2_collection.find()

    5.全文索引 一个集合只允许有一个全文索引

    全文索引限制:

    a.每次查询只能指定一个$text

    b.$text查询不能出现在$nor查询中

    c.查询中如果包含了$text,hint不再起作用

    d.mongodb的全文索引不支持中文

    > db.user3_collection.insert({name:"a"}) //准备数据
    > db.user3_collection.insert({name:"a b"})> db.user3_collection.insert({name:"a b c"})
    > db.user3_collection.insert({name:"a b c d"})> db.user3_collection.ensureIndex({name:"text"}) //单键创建全文索引 多键则是 {key_1:"text",key_2:"text"} 全部键则是 {"$**":"text"} > db.user3_collection.find({$text:{$search:"a"}}) //查询包含 a 的记录 返回结果为空 不知道为什么
    > db.user3_collection.find({$text:{$search:"a b"}}) //查询包含 a 或 b 的记录 有结果返回
    > db.user3_collection.find({$text:{$search:"a b -c"}}) //查询 包含 a 或 b 但是 不包含 c 的记录
    > db.user3_collection.find({$text:{$search:"a b"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) //相似度查询,按相似度asc排序 不使用sort是倒序

    6.地理位置索引

    经度范围: -180~180

    纬度范围: -90~90

    a、2D索引:平面地理位置索引,用于查找和存储平面上的点。

    位置表示方式:{字段名:[经度,纬度]}

    索引创建格式:db.集合.ensureIndex({字段名:"2d"})

    查询方式:

    (1)、$near查询:查询距离某个点最近的点  db.集合.find({字段名:{$near:[经度,纬度]}})

    (2)、$geoWithin查询:查询某个形状内的点

           db.集合.find({字段名:{$geoWithin:{$box:[[经度,纬度],[经度,纬度]]}}}) //矩形

           db.集合.find({字段名:{$geoWithin:{$center:[[经度,纬度],半径]}}}) //圆形

           db.集合.find({字段名:{$geoWithin:{$polygon:[[经度,纬度],[经度,纬度],[经度,纬度]]}}}) //多边形

    (3)、geoNear查询:db.runCommand({geoNear:"集合",near:[经度,纬度],maxDistance:最大距离,minDistance:最小距离,num:返回条数})

    > db.local.insert({L:[1,1]}) //插入数据
    > db.local.insert({L:[1,2]})
    > db.local.insert({L:[1,3]})
    > db.local.insert({L:[1,4]})
    > db.local.insert({L:[1,5]})
    > db.local.insert({L:[-180,-90]})
    > db.local.insert({L:[-180,90]})
    > db.local.insert({L:[180,90]})
    > db.local.insert({L:[180,-90]})
    > db.local.insert({L:[3,4]})
    > db.local.insert({L:[5,7]})
    
    > db.local.ensureIndex({L:"2d"}) //建立索引
    {
            "createdCollectionAutomatically" : true,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    
    > db.local.find({L:{$near:[1,1],$maxDistance:10}}) //2d索引中不支持 $minDistance
    
    > db.local.find({L:{$geoWithin:{$box:[[1,2],[3,5]]}}}) //查询一个矩形内的点
    
    > db.local.find({L:{$geoWithin:{$center:[[1,2],1]}}}) //查询一个矩形内的点
    
    > db.local.find({L:{$geoWithin:{$polygon:[[1,2],[3,5],[2,4]]}}}) //查询多边形内的点
    
    }
    > db.runCommand({geoNear:"local",near:[1,2],maxDistance:10,num:1})
    {
            "results" : [
                    {
                            "dis" : 0, //查找到的数据距离[1,2]的距离
                            "obj" : {
                                    "_id" : ObjectId("55f8f3bfb2c8d853c09737f0"),
                                    "L" : [
                                            1,
                                            2
                                    ]
                            }
                    }
            ],
            "stats" : {
                    "nscanned" : NumberLong(1), //扫描的数据
                    "objectsLoaded" : NumberLong(1),
                    "avgDistance" : 0, //平均距离
                    "maxDistance" : 0, //最大距离
                    "time" : 1 //花费时间
            },
            "ok" : 1
    }

    2Dsphere索引:球面地理位置索引,用于查找和存储球面上的点。

    索引创建格式:db.集合.ensureIndex({字段名:"2dsphere"})

    位置表示方式:GeoJSON 可以表示一个点 一条直线 多边形等

    详细了解:http://www.oschina.net/translate/geojson-spec?cmp

  • 相关阅读:
    cgic: CGI的C函数库
    linux下的webserver BOA及CGIC库的使用指南(转帖)
    UDP 收/发 广播包
    winsock 收发广播包
    Linux系统下UDP发送和接收广播消息小例子
    uboot里读sd卡内容
    uboot从SD卡烧写内核和文件系统
    intellij 创建一个文件自动就add到git了,这个怎么取消
    内部类和外部类之间的相互调用
    JDK8的新特性——Lambda表达式
  • 原文地址:https://www.cnblogs.com/buexplain/p/4807902.html
Copyright © 2011-2022 走看看