1.创建索引
--单索引
> db.test.ensureIndex({"username":1})
复合索引
--数字1表示username键的索引按升序存储,-1表示age键的索引按照降序方式存储。
>db.test.ensureIndex({"username":1, "age":-1})
为索引创建名字
> db.test.ensureIndex({"username":1},{"name":"testindex"})
为内嵌文档建立索引值
>db.test.ensureIndex({"comments.date":1})
2.创建唯一性索引
> db.test.ensureIndex({"userid":1},{"unique":true})
--创建唯一索引,并消除重复数据。
> db.test.ensureIndex({"userid":1},{"unique":true,"dropDups":true})
3.删除索引
> db.test.dropIndex({"userid":1})
4. 使用explain查看执行是否使用索引等
explain是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身。如:
> db.test.find().explain("executionStats")
explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息。
5. 全文索引
最初的文本搜索只是一种试验性功能,但从 2.6 版本起就成为默认功能了。但如果使用的是之前的 MongoDB,则需要使用下列代码启用文本搜索:
>db.adminCommand({setParameter:true,textSearchEnabled:true})
假设在 posts 集合中的下列文档中含有帖子文本及其标签。
{
"post_text": "enjoy the mongodb articles on tutorialspoint",
"tags": [
"mongodb",
"tutorialspoint"
]
}
我们将在 post_text 字段上创建文本索引,以便搜索帖子文本之内的内容。
>db.posts.ensureIndex({post_text:"text"})
现在我们已经在 post_text 字段上创建了文本索引,接下来搜索包含 tutorialspoint 文本内容的帖子。
>db.posts.find({$text:{$search:"tutorialspoint"}})
在返回的结果文档中,果然包含了具有 tutorialspoint 文本的帖子文本。
{
"_id" : ObjectId("53493d14d852429c10000002"),
"post_text" : "enjoy the mongodb articles on tutorialspoint",
"tags" : [ "mongodb", "tutorialspoint" ]
}
{
"_id" : ObjectId("53493d1fd852429c10000003"),
"post_text" : "writing tutorials on mongodb",
"tags" : [ "mongodb", "tutorial" ]
}
如果用的是旧版本的 MongoDB,则需使用下列代码:
>db.posts.runCommand("text",{search:" tutorialspoint "})
总之,与普通搜索相比,使用文本搜索可极大地改善搜索效率。
spring-data-mongodb使用方法
http://spring.io/blog/2014/07/17/text-search-your-documents-with-spring-data-mongodb
6. 地理空间索引
MongoDB的地理位置查询
MongoDB地理位置索引常用的有两种。
- 2d 平面坐标索引,适用于基于平面的坐标计算。也支持球面距离计算,不过官方推荐使用2dsphere索引。
- 2dsphere 几何球体索引,适用于球面几何运算
建立索引:
> db.places.ensureIndex({'coordinate':'2d'}) > db.places.ensureIndex({'coordinate':'2dsphere'})
查询方式:
而查询坐标参数则分两种:
1.坐标对(经纬度)根据查询命令的不同,$maxDistance距离单位可能是 弧度 和 平面单位(经纬度的“度”):
db.<collection>.find( { <location field> :
{ $nearSphere: [ <x> , <y> ] ,
$maxDistance: <distance in radians>
} } )
2.GeoJson $maxDistance距离单位默认为米:
db.<collection>.find( { <location field> :
{ $nearSphere :
{ $geometry :
{ type : "Point" ,
coordinates : [ <longitude> , <latitude> ] } ,
$maxDistance : <distance in meters>
} } } )
案例使用:
查询附近的人:
查询当前坐标附近的目标,由近到远排列。
可以通过$near或$nearSphere,这两个方法类似,但默认情况下所用到的索引和距离单位不同。
查询方式:
> db.places.find({'coordinate':{$near: [121.4905, 31.2646]}})
> db.places.find({'coordinate':{$nearSphere: [121.4905, 31.2646]}})
查询结果:
{
"_id" : 115,
"coordinate" : {
"longitude" : 121.4915,
"latitude" : 31.25933
},
"title" : "仅售148元,市场价298元的星程上服假日酒店全日房一间入住一天,
节假日通用,精致生活,品质享受",
"address" : "虹口区天水路90号"
}
// …(100条)
上述查询坐标[121.4905, 31.2646]附近的100个点,从最近到最远排序。
默认返回100条数据,也可以用limit()指定结果数量,如:
db.places.find({'coordinate':{$near: [121.4905, 31.2646]}}).limit(2)
指定最大距离 $maxDistance
> db.places.find({'coordinate':{$near: [121.4905, 31.2646], $maxDistance:2}})
区域内搜索:
MongoDB中的范围搜索(Inclusion)主要用$geoWithin这个命令,它又细分为3种不同类型,如下:
- $box 矩形
- $center 圆(平面),$centerSphere圆(球面)$center和$centerSphere在小范围内的应用几乎没差别(除非这个圆半径几百上千公里)。
- $polygon 多边形
(A) 矩形查询:
> db.places.find(
{
coordinate : {
$geoWithin : {
$box :[ [ 121.44, 31.25 ] , [ 121.5005, 31.2846 ] ]
}
}
}
)
(B) 圆形查询
应用场景有:地图搜索租房信息
查询以某坐标为圆心,指定半径的圆内的数据。
前面已提到,圆形区域搜索分为$center和$centerSphere这两种类型,它们的区别主要在于支持的索引和默认距离单位不同。2d索引能同时支持$center和$centerSphere,2dsphere索引支持$centerSphere。关于距离单位,$center默认是度,$centerSphere默认距离是弧度。
> db.places.find({'coordinate':{$geoWithin:{$centerSphere:[ [121.4905, 31.2646] ,
0.6/111] }}})
db.places.find({'coordinate':{$geoWithin:{$centerSphere:[ [121.4905, 31.2646] ,
0.6/6371] }}})
查询结果:
{
"_id" : 115,
"coordinate" : {
"longitude" : 121.4915,
"latitude" : 31.25933
},
"title" : "仅售148元,市场价298元的星程上服假日酒店全日房一间入住一天,节假日通用,
精致生活,品质享受",
"address" : "虹口区天水路90号"
}
...
(C) 多边形查询
复杂区域内的查询,这个应用场景比较少见。指定至少3个坐标点,查询方式如下(五边形):
> db.places.find( { coordinate : { $geoWithin : { $polygon : [
[121.45183 , 31.243816] ,
[121.533181, 31.24344] ,
[121.535049, 31.208983] ,
[121.448955, 31.214913] ,
[121.440619, 31.228748]
] } } } )
附近的餐厅:
假设需要以当前坐标为原点,查询附近指定范围内的餐厅,并直接显示距离。
这个需求用前面提到的$near是可以实现的,但是距离需要二次计算。这里我们用$geoNear这个命令查询。
$geoNear与$near功能类似,但提供更多功能和返回更多信息,官方文档是这么解释的
$near方法查询后会对结果集对距离进行排序,而$geoWithin是无序的
> db.runCommand( { geoNear: "places", near: [ 121.4905, 31.2646 ], spherical: true,
maxDistance:1/6371, num:2 })
{
"ns" : "mongo_test.places",
"near" : "1110001100111100001011010110010111001000110011111101",
"results" : [
{
"dis" : 0.00009318095248858048,
"obj" : {
"_id" : 115,
"coordinate" : {
"longitude" : 121.4915,
"latitude" : 31.25933
},
"title" : "仅售148元,市场价298元的星程上服假日酒店全日房一间入住一天,
节假日通用,精致生活,品质享受",
"address" : "虹口区天水路90号"
}
},
{
"dis" : 0.00010610660597329082,
"obj" : {
"_id" : 465,
"coordinate" : {
"longitude" : 121.48406,
"latitude" : 31.26202
},
"title" : "【四川北路】热烈庆祝康骏会馆成立8周年!仅售169元!市场价399元的
康骏会馆四川北路一店(仅限3星级技师)全身精油按摩一人次!全程约90分钟!
男女不限!仅限四川北路一店使用,非本市所有门店通用!拉手券消费仅限每日19:00前!
健康有道,骏越万里!",
"address" : "虹口区四川北路1896号-1904号201室"
}
}
],
"stats" : {
"time" : 0,
"btreelocs" : 0,
"nscanned" : 18,
"objectsLoaded" : 12,
"avgDistance" : 0.00009964377923093564,
"maxDistance" : 0.0001064199324957278
},
"ok" : 1
}
来源:oschina
链接:https://my.oschina.net/u/1403215/blog/741628