MongoDB的索引(三)

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




 

posted @ 2015-08-24 01:26  dcz1001  阅读(261)  评论(0编辑  收藏  举报