上篇文章中咱們介紹了MongoDB中索引的簡單操做,建立、查看、刪除等基本操做,不過上文咱們只介紹了一種類型的索引,本文咱們來看看其餘類型的索引。 json
本文是MongoDB系列的第十篇文章,瞭解前面的文章有助於更好的理解本文:數組
1.Linux上安裝MongoDB
2.MongoDB基本操做
3.MongoDB數據類型
4.MongoDB文檔更新操做
5.MongoDB文檔查詢操做(一)
6.MongoDB文檔查詢操做(二)
7.MongoDB文檔查詢操做(三)
8.MongoDB查看執行計劃
9.初識MongoDB中的索引spa
咱們在上文介紹過,咱們往集合中添加文檔時,默認狀況下MongoDB都會幫助咱們建立一個名爲_id
的字段,這個字段就是一個索引。默認狀況下,通常的集合都會幫咱們建立這個字段做爲索引,但也有一些集合不會將_id
默認做爲索引,好比固定集合,這個咱們後面的文章會詳細說到這個問題。3d
若是咱們的查詢條件有多個的話,咱們能夠對這多個查詢條件都創建索引,好比咱們能夠對文檔中的x和y字段都創建索引,以下:code
db.sang_collect.ensureIndex({x:1,y:-1})
此時執行以下查詢語句時就會用到這個複合索引:排序
db.sang_collect.find({x:1,y:999})
小夥伴們也能夠經過查看查詢計劃來肯定確實使用到了上文建立好的索引。索引
顧名思義,過時索引就是一種會過時的索引,在索引過時以後,索引對應的數據會被刪除,建立方式以下:遊戲
db.sang_collect.ensureIndex({time:1},{expireAfterSeconds:30})
expireAfterSeconds表示索引的過時時間,單位爲秒。time表示索引的字段,time的數據類型必須是ISODate或者ISODate數組,不然的話,當索引過時以後,time的數據就不會被刪除。圖片
全文索引雖然好用,惋惜不支持中文,咱們這裏就先作一個簡單的瞭解。 文檔
好比,個人數據集以下:
{ "_id" : ObjectId("59f5a3da1f9e8e181ffc3189"), "x" : "Java C# Python PHP" } { "_id" : ObjectId("59f5a3da1f9e8e181ffc318a"), "x" : "Java C#" } { "_id" : ObjectId("59f5a3da1f9e8e181ffc318b"), "x" : "Java Python" } { "_id" : ObjectId("59f5a3da1f9e8e181ffc318c"), "x" : "PHP Python" } { "_id" : ObjectId("59f5a4541f9e8e181ffc318d"), "x" : "C C++" }
咱們能夠給x字段創建一個全文索引,建立方式以下:
db.sang_collect.ensureIndex({x:"text"})
MongoDB會自動對x字段的數據進行分詞,而後咱們就能夠經過以下語句進行查詢:
db.sang_collect.find({$text:{$search:"Java"}})
此時x中包含Java的文檔都會被查詢出來。若是想查詢既包含Java又包含C#的文檔,操做以下:
db.sang_collect.find({$text:{$search:"\"Java C#\""}})
用一對雙引號將查詢條件括起來,若是想查詢包含PHP或者Python的文檔,操做以下:
db.sang_collect.find({$text:{$search:"PHP Python"}})
若是想查詢既有PHP,又有Python,可是又不包括Java的文檔,以下:
db.sang_collect.find({$text:{$search:"PHP Python -Java"}})
創建了全文索引以後,咱們也能夠查看查詢結果的類似度,使用$meta,以下:
db.sang_collect.find({$text:{$search:"PHP Python"}},{score:{$meta:"textScore"}})
此時查詢結果中會多出一個score字段,該字段的值越大,表示類似度越高,咱們能夠根據score利用sort來對其進行排序,以下:
db.sang_collect.find({$text:{$search:"PHP Python"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
全文索引目前看起來功能仍是很強大,惋惜暫時不支持中文,不過網上對此也有不少解決方案,小夥伴們能夠自行搜索查看。
地理空間索引能夠分爲兩類:
1.2d索引,能夠用來存儲和查找平面上的點。
2.2d sphere索引,能夠用來存儲和查找球面上的點。
2d索引通常咱們能夠用在遊戲地圖中。
向集合中插入一條記錄點的數據:
db.sang_collect.insert({x:[90,0]})
插入數據的格式爲[經度,緯度],取值範圍,經度[-180,180],緯度[-90,90]。數據插入成功以後,咱們先經過以下命令建立索引:
db.sang_collect.ensureIndex({x:"2d"})
而後經過$near咱們能夠查詢某一個點附近的點,以下:
db.sang_collect.find({x:{$near:[90,0]}})
默認狀況下返回該點附近100個點,咱們能夠經過$maxDistance來設置返回的最遠距離:
db.sang_collect.find({x:{$near:[90,0],$maxDistance:99}})
咱們也能夠經過$geoWithin查詢某個形狀內的點,好比查詢矩形中的點:
db.sang_collect.find({x:{$geoWithin:{$box:[[0,0],[91,1]]}}})
兩個座標點用來肯定矩形的位置。
查詢圓中的點:
db.sang_collect.find({x:{$geoWithin:{$center:[[0,0],90]}}})
參數分別表示圓的圓心和半徑。
查詢多邊形中的點:
db.sang_collect.find({x:{$geoWithin:{$polygon:[[0,0],[100,0],[100,1],[0,1]]}}})
這裏能夠填入任意多個點,表示多邊形中的各個點。
2dsphere適用於球面類型的地圖,它的數據類型是GeoJSON格式的,咱們能夠在http://geojson.org/地址上查看...,好比咱們描述一個點,GeoJSON以下:
{ "_id" : ObjectId("59f5e0571f9e8e181ffc3196"), "name" : "shenzhen", "location" : { "type" : "Point", "coordinates" : [ 90.0, 0.0 ] } }
描述線,GeoJSON格式以下:
{ "_id" : ObjectId("59f5e0d01f9e8e181ffc3199"), "name" : "shenzhen", "location" : { "type" : "LineString", "coordinates" : [ [ 90.0, 0.0 ], [ 90.0, 1.0 ], [ 90.0, 2.0 ] ] } }
描述多邊形,GeoJSON格式以下:
{ "_id" : ObjectId("59f5e3f91f9e8e181ffc31d0"), "name" : "beijing", "location" : { "type" : "Polygon", "coordinates" : [ [ [ 0.0, 1.0 ], [ 0.0, 2.0 ], [ 1.0, 2.0 ], [ 0.0, 1.0 ] ] ] } }
還有其餘的類型,具體小夥伴們能夠參考http://geojson.org/。有了數據以後,咱們能夠經過以下操做來建立地理空間索引了:
db.sang_collect.ensureIndex({location:"2dsphere"})
好比我想查詢和深圳這個區域有交集的文檔,以下:
var shenzhen = db.sang_collect.findOne({name:"shenzhen"}) db.sang_collect.find({location:{$geoIntersects:{$geometry:shenzhen.location}}})
這裏的查詢結果是和深圳這個區域有交集的都會查到(好比通過深圳的高速公路、鐵路等),咱們也能夠只查詢深圳市內的區域(好比深圳市內全部的學校),以下:
var shenzhen = db.sang_collect.findOne({name:"shenzhen"}) db.sang_collect.find({location:{$within:{$geometry:shenzhen.location}}})
也能夠查詢騰訊附近的其餘位置,以下:
var QQ = db.sang_collect.findOne({name:"QQ"}) db.sang_collect.find({location:{$near:{$geometry:QQ.location}}})
位置每每只是咱們查詢的一個條件,好比我要查詢深圳市內全部的學校,那我得再增長一個查詢條件,以下:
var shenzhen = db.sang_collect.findOne({name:"shenzhen"}) db.sang_collect.find({location:{$within:{$geometry:shenzhen.location}},name:"QQ"})
其餘的查詢條件跟在後面就好了。
好了,MongoDB中的索引問題咱們就說到這裏,小夥伴們有問題歡迎留言討論。
參考資料:
1.《MongoDB權威指南第2版》
更多資料請關注公衆號: