欢迎投稿

今日深度:

mongoDB常见的查询索引(三),mongodb查询索引

mongoDB常见的查询索引(三),mongodb查询索引


1. _id索引

    _id索引是绝大多数集合默认建立的索引     对于每个插入的数据,MongoDB会自动生成一条唯一的_id字段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > db.jerome_2.collection.insert({x:2}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.collection.getIndexes() [     {         "v" : 1,         "key" : {             "_id" : 1         },         "name" "_id_",         "ns" "jerome.jerome_2.collection"     } ] > db.jerome_2.collection.findOne() "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 }

2. 单键索引

    1.单间索引是最普通的索引     2. 与_id索引不同,单间索引不会自动创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 > db.jerome_2.collection.ensureIndex({x:1}) # 创建索引 {     "createdCollectionAutomatically" false,     "numIndexesBefore" : 1,     "numIndexesAfter" : 2,     "ok" : 1 } > db.jerome_2.collection.getIndexes() [     {         "v" : 1,         "key" : {             "_id" : 1         },         "name" "_id_",         "ns" "jerome.jerome_2.collection"     },     {         "v" : 1,         "key" : {             "x" : 1         },         "name" "x_1",         "ns" "jerome.jerome_2.collection"     } ] > db.jerome_2.collection.find({x:1}) #使用创建的索引查询 "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }


3. 多建索引

    多键索引和单键索引创建形式相同,区别在于字段的值。         单键索引:值为一个单一的值,例如字符串,数字或者日期。         多键索引:值具有多个记录,例如数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 > db.jerome_2.collection.getIndexes() [     {         "v" : 1,         "key" : {             "_id" : 1         },         "name" "_id_",         "ns" "jerome.jerome_2.collection"     },     {         "v" : 1,         "key" : {             "x" : 1         },         "name" "x_1",         "ns" "jerome.jerome_2.collection"     } ] > db.jerome_2.collection.find() "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 } "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 } > db.jeroem_2.collection.insert({x:[1,2,3,4,5]}) #插入一条数组数据,对于这条数据来讲,mongodb为其创建了一个多件索引 WriteResult({ "nInserted" : 1 })


4. 复合索引


1 2 3 4 5 6 7 8 9 10 > db.jerome_2.collection.ensureIndex({x:1,y:1}) #创建 {     "createdCollectionAutomatically" false,     "numIndexesBefore" : 2,     "numIndexesAfter" : 3,     "ok" : 1 } > db.jerome_2.collection.find({x:1,y:2}) #使用 "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }

5. 过期索引

    1. 过期索引:是在一段时间后会过期的索引。     2. 在索引过期后,相应的数据会被删除     3. 这适合存储一些在一段时间之后会失效的数据,比如用户的登陆信息、存储的日志等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 > db.jerome_2.collection.ensureIndex({time:1},{expireAfterSeconds:30}) #创建过期索引,过期时间30秒 {     "createdCollectionAutomatically" false,     "numIndexesBefore" : 3,     "numIndexesAfter" : 4,     "ok" : 1 } > db.jerome_2.collection.insert({time:new Date()}) #插入数据测试 WriteResult({ "nInserted" : 1 }) > db.jerome_2.collection.find() "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 } "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 } "_id" : ObjectId("55700b17f2824fa15224e20e"), "time" : ISODate("2015-06-04T08:23:51.531Z") } > db.jerome_2.collection.find() "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 } "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 } "_id" : ObjectId("55700b17f2824fa15224e20e"), "time" : ISODate("2015-06-04T08:23:51.531Z") } > db.jerome_2.collection.find() #时间过了就找不到了 "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 } "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
使用限制     1. 存储在过期索引字段的值必须是指定的时间类型。(必须是ISODate或者ISODate数组,不能使用时间戳,否则不能被自动删除)     2. 如果指定了ISODate数组,则按照最小的时间进行删除。     3. 过期索引不能是复合索引。     4. 删除时间不是精确的。(删除过程是由后台程序没60s跑一次,而且删除也需要一些时间,所以存在误差)

6.全文索引

对字符串与字符串数组创建全文可搜索的索引      使用情况:{author:"",titile;"",article:""}   创建方法     1. db.articles.ensureIndex({key:"text"})     2. db.articles.ensureIndex({key_1:"text",key_2:"text"})     3. db.articles.ensureIndex({"$**":"text"}) 使用     1. db.articles.find({$text:{$search:"aa"}})     2. db.articles.find({$text:{$search:"aa bb cc"}}) #空格表示或
    3. db.articles.find({$text:{$search:"aa bb -cc"}}) #-cc 表示不包含cc
    4. db.articles.find({$text:{$search:"\"aa\" bb cc"}}) #“”,加引号,表示与
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 > db.jerome_2.ensureIndex({"article":"text"}) #创建全文索引 {     "createdCollectionAutomatically" true,     "numIndexesBefore" : 1,     "numIndexesAfter" : 2,     "ok" : 1 } > db.jerome_2.insert({"article":"aa bb cc dd ee"}) #插入测试数据 WriteResult({ "nInserted" : 1 }) > db.jerome_2.insert({"article":"aa bb rr gg zz"}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.insert({"article":"aa bb"}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.insert({"article":"aa bb cc zz ff ww"}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.find({$text:{$search:"aa"}}) #查找 "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" "aa bb rr gg zz" } "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" "aa bb cc dd ee" } "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww" } "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" "aa bb" } > db.jerome_2.find({$text:{$search:"ff"}}) "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww" } > db.jerome_2.find({$text:{$search:"aa bb cc"}}) "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" "aa bb rr gg zz" } "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" "aa bb cc dd ee" } "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww" } "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" "aa bb" } > db.jerome_2.find({$text:{$search:"aa bb -cc"}}) "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" "aa bb rr gg zz" } "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" "aa bb" } > db.jerome_2.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}}) "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" "aa bb cc dd ee" } "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww" }

全文索引相似度     $meta操作符:{score:{$meta:"textScore"}},卸载查询条件后面可以反悔返回结果的相似度,与sort一起使用可以达到很好的实用效果。
1 2 3 4 5 6 7 8 9 10 11 > db.jerome_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}) #score越高,相似度越高。 "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" "aa bb rr gg zz""score" : 1.2 } "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" "aa bb cc dd ee""score" : 1.2 } "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww""score" : 1.1666666666666667 } "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" "aa bb""score" : 1.5 } > db.jerome_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) #根据score进行排序 "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" "aa bb""score" : 1.5 } "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" "aa bb cc dd ee""score" : 1.2 } "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" "aa bb rr gg zz""score" : 1.2 } "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" "aa bb cc zz ff ww""score" : 1.1666666666666667 }
    使用限制         1. 每次查询只能指定一个$text查询         2. $text查询不能出现在$nor查询中         3. 查询中如果包含了$text,hint不再起作用         4. MongoDB去做你问索引现在还不支持中文

7.地理位置索引

概念:将一些点的位置存储在MongoDB中,创建索引后,可以按照位置来查找其他点。  分类:     1. 2d索引,用于存储和查找平面上的点     2. 2dsphere索引,用于存储和查找球面上的点 查找方式:     1. 查找距离某个点一定距离内的点。     2. 查找包含在某区域内的点。

2d索引

创建:db.location.ensureIndex({"w":"2d"})     位置表示方式:经纬度[经度,纬度]     取值范围:经度[-180,180] 纬度[-90,90] 查询方式     1. $near查询:查询距离某个点最近的点     2. $geoWithin查询:查询某个形状内的点 1. $near查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 > db.location.ensureIndex({"w":"2d"}) #创建2d索引 > db.location.insert({w:[1,1]}) #插入测试数据 WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[1,2]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[2,3]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[100,80]}) WriteResult({ "nInserted" : 1 }) > db.location.find({w:{$near:[1,1]}}) #会返回100个,理你最近的点 "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] } > db.location.find({w:{$near:[1,1],$maxDistance:2}}) #可以使用maxDistance限制(near不能使用minDistance "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
2. $geoWithin查询
形状的表示:     1. $box:矩形,使用{$box:[[<x1>,<y1>],[<x2>,<y2>]]}表示     2. $center:圆形,使用{$center:[[<x1>,<y1>],r]}表示     3. $polygon:多边形,使用{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}表示 例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 > db.location.find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}}) #矩形 "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } > db.location.find({w:{$geoWithin:{$box:[[1,2],[2,3]]}}}) "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } > db.location.find({w:{$geoWithin:{$center:[[0,0],100]}}}) #圆形,100是半径 "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } > db.location.find({w:{$geoWithin:{$center:[[0,0],1000]}}}) "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] } "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } > db.location.find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1]]}}}) #多边形查询(各个点围成的多边形的范围) "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] } > db.location.find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1000],[1001,0]]}}}) "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] } "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] } "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] } "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }

3. 使用geoNear查询
geoNear使用runCommand命令进行使用 db.runCommand(     {getNear:<collection>,     near:[x,y],     minDistance:(对2d索引无效)     maxDistance:     num: } )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 > db.runCommand({geoNear:"location",near:[1,2],maxDistance:10,num:1}) {     "results" : [         {             "dis" : 0,             "obj" : {                 "_id" : ObjectId("5572a965aba41684d6e8826d"),                 "w" : [                     1,                     2                 ]             }         }     ],     "stats" : {         "nscanned" : NumberLong(1),         "objectsLoaded" : NumberLong(1),         "avgDistance" : 0,         "maxDistance" : 0,         "time" : 2     },     "ok" : 1 }

球面地理位置索引

概念:球面地理位置索引 创建方式:db.collection.ensureIndex({w:"2dsphere"}) 位置表示方式: GeoJson:描述一个点,一条直线,多边形等形状 格式:{type:"",coordinates:[<coordinates>]} 支持$minDistance与$maxDistance

创建索引比较重要属性介绍

格式     db.collection.ensureIndex({param},{param}) #第二个参数是索引的属性
比较重要的属性有:名字、唯一性、稀疏性、是否定时删除
1. 名字,name指定:db.collection.ensureIndex({},{name:""})     默认命名格式是如下这样的     单键索引,1和-1,命名是根据key+_1/-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 > db.jerome_2.ensureIndex({x:1}) > db.jerome_2.ensureIndex({y:-1}) > db.jerome_2.getIndexes() [     {         "v" : 1,         "key" : {             "_id" : 1         },         "name" "_id_",         "ns" "jerome.jerome_2"     },     {         "v" : 1,         "key" : {             "x" : 1         },         "name" "x_1",         "ns" "jerome.jerome_2"     },     {         "v" : 1,         "key" : {             "y" : -1         },         "name" "y_-1",         "ns" "jerome.jerome_2"     }

    复合索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 > db.jerome_2.ensureIndex({x:1,y:-1}) > db.jerome_2.ensureIndex({x:1,y:-1,z:1}) > db.jerome_2.getIndexes() [     {         "v" : 1,         "key" : {             "x" : 1,             "y" : -1         },         "name" "x_1_y_-1",         "ns" "jerome.jerome_2"     },     {         "v" : 1,         "key" : {             "x" : 1,             "y" : -1,             "z" : 1         },         "name" "x_1_y_-1_z_1",         "ns" "jerome.jerome_2"     } ]
mongodb对索引限制是125字节,所以我们需要自定义索引名字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 > db.jerome_2.ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index"}) > db.jerome_2.getIndexes() [     {         "v" : 1,         "key" : {             "x" : 1,             "y" : 1,             "z" : 1,             "m" : 1         },         "name" "normal_index",         "ns" "jerome.jerome_2"     } ] > db.jerome_2.dropIndex("normal_index") "nIndexesWas" : 7, "ok" : 1 }

2. 唯一性,unique指定:db.collection.ensureIndex({},{unique:true/false})
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 > db.jerome.ensureIndex({m:1,n:1},{unique:true}) {     "createdCollectionAutomatically" true,     "numIndexesBefore" : 1,     "numIndexesAfter" : 2,     "ok" : 1 } > db.jerome.insert({m:1,n:2}) WriteResult({ "nInserted" : 1 }) > db.jerome.insert({m:1,n:2}) WriteResult({     "nInserted" : 0,     "writeError" : {         "code" : 11000,         "errmsg" "insertDocument :: caused by :: 11000 E11000 duplicate key error index: jerome.jerome.$m_1_n_1  dup key: { : 1.0, : 2.0 }"     } })

3. 稀疏性,sparse指定:db.collection.ensureIndex({},{sparse:true/false}) 默认创建的索引是不稀疏的。 因为MongoDB没有固定的格式,插入的时候可能插入不存在的字段,比如x:1,MongoDB会为这条不存在的字段创建索引,如果不希望发现这样的事情可以指定稀疏索引为true,就不会为不存在的字段创建索引了。可以减少磁盘暂用和增大插入速度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 > db.jerome.insert({"m":1}) WriteResult({ "nInserted" : 1 }) > db.jerome.insert({"n":1}) WriteResult({ "nInserted" : 1 }) > db.jerome.find({m:{$exists:true}}) #exists查找数据集合中一个字段存在或者不存在的记录 "_id" : ObjectId("55729ec1aba41684d6e8826a"), "m" : 1 } "_id" : ObjectId("55729d5caba41684d6e88268"), "m" : 1, "n" : 2 } > db.jerome.ensureIndex({m:1},{sparse:true}) #创建稀疏索引 {     "createdCollectionAutomatically" false,     "numIndexesBefore" : 2,     "numIndexesAfter" : 3,     "ok" : 1 } > db.jerome.find({m:{$exists:false}}) #MongoDB内部问题,所以找得到,通过下面强制指定索引 "_id" : ObjectId("55729ec7aba41684d6e8826b"), "n" : 1 } > db.jerome.find({m:{$exists:false}}).hint("m_1"#下面这条记录,不存在m字段,所以不会创建索引,所以查不到记录 
注意:不能在稀疏索引上查找这个字段不存在的记录。
4. 过期索引     前面已介绍

www.htsjk.Com true http://www.htsjk.com/shujukunews/8591.html NewsArticle mongoDB常见的查询索引(三),mongodb查询索引 1. _id索引 _id索引是绝大多数集合默认建立的索引 对于每个插入的数据,MongoDB会自动生成一条唯一的_id字段。 12345678910111213141516 db.jerome_2...
相关文章
    暂无相关文章
评论暂时关闭