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

  • 相关阅读:
    UVa 10118 记忆化搜索 Free Candies
    CodeForces 568B DP Symmetric and Transitive
    UVa 11695 树的直径 Flight Planning
    UVa 10934 DP Dropping water balloons
    CodeForces 543D 树形DP Road Improvement
    CodeForces 570E DP Pig and Palindromes
    HDU 5396 区间DP 数学 Expression
    HDU 5402 模拟 构造 Travelling Salesman Problem
    HDU 5399 数学 Too Simple
    CodeForces 567F DP Mausoleum
  • 原文地址:https://www.cnblogs.com/buexplain/p/4807902.html
Copyright © 2011-2022 走看看