MongoDB的索引(三)

来源:互联网 发布:彩票代购源码 编辑:程序博客网 时间:2024/06/06 01:16

MongoDB的索引:

1. _id索引

该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段。


2. 单键索引

单键索引是最普通的索引,它不会自动创建,需要手动创建。

例如:dm.bochao_collection.ensureIndex({name:"zhangsan"})

创建了一个name=zhangsan的索引

> db.bochao_collection.ensureIndex({x:11}){        "createdCollectionAutomatically" : false,        "numIndexesBefore" : 1,        "numIndexesAfter" : 2,        "ok" : 1}> db.bochao_collection.getIndexes()[        {                "v" : 1,                "key" : {                        "_id" : 1                },                "name" : "_id_",                "ns" : "bochao.bochao_collection"        },        {                "v" : 1,                "key" : {                        "x" : 11                },                "name" : "x_11",                "ns" : "bochao.bochao_collection"        }]


3. 多键索引

多键索引与单键索引类似,区别在于字段的值。

单键索引:值为一个单一的值,例如字符串,数字或者日期。

多键索引: 值具有多个记录,例如数组。


4. 复合索引

当使用多个查询条件时候,可以创建复合索引。

> db.bochao_collection.ensureIndex({x:11,y:22}){        "createdCollectionAutomatically" : false,        "numIndexesBefore" : 2,        "numIndexesAfter" : 3,        "ok" : 1}> db.bochao_collection.getIndexes()[        {                "v" : 1,                "key" : {                        "_id" : 1                },                "name" : "_id_",                "ns" : "bochao.bochao_collection"        },        {                "v" : 1,                "key" : {                        "x" : 11                },                "name" : "x_11",                "ns" : "bochao.bochao_collection"        },        {                "v" : 1,                "key" : {                        "x" : 11,                        "y" : 22                },                "name" : "x_11_y_22",                "ns" : "bochao.bochao_collection"        }]


5. 过期索引

过期索引是在一定的时间会自动过期失效的索引

在索引过期后,相应的数据会被自动删除

这将比较适合存储一些在一段时间后会失效的数据,如用户登录信息、日志信息等等


注意:

<1>. 存储在过期索引的字段值类型必须是时间类型,必须是ISODate或者是ISO数组,不能使用时间戳,否则不能自动清除数据。

> db.bochao_collection.ensureIndex({time:1},{expireAfterSeconds:30})
db.bochao_collection.insert({time:new Date(), address:"北京市昌平区"})

这会在30秒钟后自动删除该条数据

<2>. 如果指定了ISODate数组,则按照最小的时间进行删除。也就是说如果有一个最小的时间到达了,则删除该条数据。

<3>. 过期索引不能创建复合索引

<4>. 索引过期按指定时间删除是不精确的。 因为删除过程是后台进程每60S执行一次,有误差


6. 全文索引

对字符串与字符串数组创建全文可搜索的索引

<1>. 创建全文索引

> db.bochao_collection.ensureIndex({article:"text"}){        "createdCollectionAutomatically" : true,        "numIndexesBefore" : 1,        "numIndexesAfter" : 2,        "ok" : 1}

<2>. 使用全文索引查询

> db.bochao_collection.find({$text:{$search:"aa"}}){ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" }{ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }

MongoDB的一个集合中只能创建一个全文索引

# 查询包含多个条件字符串(或的关系),如下:

> db.bochao_collection.find({$text:{$search:"aa bb cc"}}){ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" }{ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }

# 查询包含多个条件字符串(与的关系),如下:

> db.bochao_collection.find({$text:{$search:"\"aa\", \"bb\", \"cc\""}}){ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" }

# 按照条件全文检索并且不包含某个字符的查询,如下

> db.bochao_collection.find({$text:{$search:"aa bb -cc"}}){ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }


# 全文索引的相似度,使用这样的语法: score:{$meta:"textScore"}

写在查询条件之后可以返回结果的相似度,与sort一起使用,可以达到很好的使用效果。

> db.bochao_collection.find({$text:{$search:"aa bb"}}){ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" }{ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }{ "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb" }> db.bochao_collection.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}){ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd", "score" : 1.25 }{ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg", "score" : 1.25 }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee", "score" : 1.25 }{ "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb", "score" : 1.5 }> db.bochao_collection.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}){ "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb", "score" : 1.5 }{ "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd", "score" : 1.25 }{ "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg", "score" : 1.25 }{ "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee", "score" : 1.25 }

利用这个功能可以实现一个不错的全文检索功能哦

注意:

每次查询,只能使用$text查询

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

查询中如果包含了$text,hint将失效

全文索引不支持中文


# 索引的重要属性:


<1>. 索引的名称:自定义索引的名称

> db.bochao_collection.ensureIndex({dcz:1000}, {name:"dczIndex"}){        "createdCollectionAutomatically" : false,        "numIndexesBefore" : 4,        "numIndexesAfter" : 5,        "ok" : 1
       {               "v" : 1,               "key" : {                       "dcz" : 1000               },               "name" : "dczIndex",               "ns" : "bochao.bochao_collection"       }


删除索引:

> db.bochao_collection.dropIndex("dczIndex"){ "nIndexesWas" : 5, "ok" : 1 }

<2>. 索引的唯一性,unique指定

> db.bochao_c.ensureIndex({m:1,n:1},{unique:true}){        "createdCollectionAutomatically" : true,        "numIndexesBefore" : 1,        "numIndexesAfter" : 2,        "ok" : 1}

这样创建后就不能插入两条一样的M,N数据了。


<3>. 稀疏索引,使用sparse关键字:

避免为不必要的字段上创建索引,创建语法是:db.collection.ensureIndex({},{sparse:true/false})

> db.bochao3.ensureIndex({m:1},{sparse:true}){        "createdCollectionAutomatically" : false,        "numIndexesBefore" : 1,        "numIndexesAfter" : 2,        "ok" : 1}


7. 地址位置索引

将一些点的位置存储在MongoDB 中,创建索引后,可以按照位置来查找其他点。

子分类:

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

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


查找方式:

1. 查找距离某个点一定距离内的点

2. 查找包含在某区域内的点


# 创建2d索引

创建语法:db.collection.ensureIndex({w:"2d"})

2d位置表示方法:经纬度[经度,纬度],取值范围:经度[-180,180] 纬度[-90,90]

查询方式:

1. $near查询:查询距离某个点最近的点:

插入几个平面坐标(经纬度):
> db.location.insert({w:[30,60]})WriteResult({ "nInserted" : 1 })> db.location.insert({w:[1,2]})WriteResult({ "nInserted" : 1 })> db.location.insert({w:[30,80]})WriteResult({ "nInserted" : 1 })> db.location.insert({w:[180,40]})WriteResult({ "nInserted" : 1 })> db.location.insert({w:[127,20]})WriteResult({ "nInserted" : 1 })
查询一下:> db.location.find(){ "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] }{ "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] }{ "_id" : ObjectId("55db2d01a0319a75b8c83ba3"), "w" : [ 30, 80 ] }{ "_id" : ObjectId("55db2d0ba0319a75b8c83ba4"), "w" : [ 180, 40 ] }{ "_id" : ObjectId("55db2d13a0319a75b8c83ba5"), "w" : [ 127, 20 ] }
查询距离经纬度[1,1]最近的,看到会返回了全部坐标点,MongoDB默认会返回100个最近的点> db.location.find({w:{$near:[1,1]}}){ "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] }{ "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] }{ "_id" : ObjectId("55db2d01a0319a75b8c83ba3"), "w" : [ 30, 80 ] }{ "_id" : ObjectId("55db2d13a0319a75b8c83ba5"), "w" : [ 127, 20 ] }{ "_id" : ObjectId("55db2d0ba0319a75b8c83ba4"), "w" : [ 180, 40 ] }可以使用$maxDistance关键字来做限制> db.location.find({w:{$near:[1,1], $maxDistance:80}}){ "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] }{ "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] }


2. 使用$geoWithin查询:查询某个形状内的点

形状的表示:

<1>. $box:矩形,使用{$box:[[<x1>,<y1>],[<x2>,<y2>]]}表示

> db.location.find({w:{$geoWithin:{$box:[[10,20],[80,80]]}}}){ "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] }{ "_id" : ObjectId("55df169ac7913b1f63dd27e4"), "w" : [ 10, 30 ] }{ "_id" : ObjectId("55df16a3c7913b1f63dd27e5"), "w" : [ 20, 30 ] }{ "_id" : ObjectId("55df16c1c7913b1f63dd27eb"), "w" : [ 10, 60 ] }{ "_id" : ObjectId("55df16a6c7913b1f63dd27e6"), "w" : [ 20, 50 ] }{ "_id" : ObjectId("55df16aac7913b1f63dd27e7"), "w" : [ 50, 50 ] }{ "_id" : ObjectId("55df16afc7913b1f63dd27e8"), "w" : [ 50, 80 ] }


<2>. $center:圆形,使用{$center:[[<x1>,<y1>],r]}表示

> db.location.find({w:{$geoWithin:{$center:[[10,20],40]}}}){ "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] }{ "_id" : ObjectId("55df169ac7913b1f63dd27e4"), "w" : [ 10, 30 ] }{ "_id" : ObjectId("55df16a3c7913b1f63dd27e5"), "w" : [ 20, 30 ] }{ "_id" : ObjectId("55df16c1c7913b1f63dd27eb"), "w" : [ 10, 60 ] }{ "_id" : ObjectId("55df16a6c7913b1f63dd27e6"), "w" : [ 20, 50 ] }


<3>. $polygon:多边形,使用{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}表示

> db.location.find({w:{$geoWithin:{$polygon:[[10,20],[40,30],[90,30]]}}}){ "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] }

<4>. geoNear查询:geoNear使用runCommand命令进行使用,如下:

db.runCommand({geoNear:<collection>,

                             near:[x,y],

                             minDistance:, (对2d索引无效)

                             maxDistance:,

                             num:

                             ...})

> db.runCommand({geoNear:"location",near:[10,20],maxDistance:10,num:2}){        "results" : [                {                        "dis" : 0,                        "obj" : {                                "_id" : ObjectId("55df1696c7913b1f63dd27e3"),                                "w" : [                                        10,                                        20                                ]                        }                },                {                        "dis" : 10,                        "obj" : {                                "_id" : ObjectId("55df169ac7913b1f63dd27e4"),                                "w" : [                                        10,                                        30                                ]                        }                }        ],        "stats" : {                "nscanned" : 22,                "objectsLoaded" : 2,                "avgDistance" : 5,                "maxDistance" : 10,                "time" : 4        },        "ok" : 1


# 创建2dsphere索引

创建方式:db.collection.ensureIndex({w:"2dsphere"})

位置表示方式

GeoJSON:描述一个点,一条直线,多边形等形状。

格式:{type:"", coordinates:[<coordinates>]}

查询方式与2d索引方式类似,支持$minDistance与$maxDistance





0 0