2014-01-05 43 views
1

我有很難的東西,應該是微不足道的....蒙戈複合索引
我有以下的profile文件結構:
與地理位置不工作

{ 
    pid:"profileId", 
    loc : { 
     "lat" : 32.082156661684621, 
     "lon" : 34.813229013156551, 
     "locTime" : NumberLong(0) 
     } 
    age:29 
} 

一個常見的用例在我的應用程序是檢索按年齡過濾附近的配置文件。

{ "loc" : { "$near" : [ 32.08290052711715 , 34.80888522811172] , "$maxDistance" : 179.98560115190784}, "age" : { "$gte" : 0 , "$lte" : 33}} 

所以我創建了以下複合索引:

{ 'loc':2d , age:1} 

而且不管我做什麼,我不能讓與創建的索引(也試圖與提示)運行查詢
這是查詢生成的解釋:

{ 
    "cursor" : "GeoSearchCursor" , 
    "isMultiKey" : false , 
    "n" : 4 , 
    "nscannedObjects" : 4 , 
    "nscanned" : 4 , 
    "nscannedObjectsAllPlans" : 4 , 
    "nscannedAllPlans" : 4 , 
    "scanAndOrder" : false , 
    "indexOnly" : false , 
    "nYields" : 0 , 
    "nChunkSkips" : 0 , 
    "millis" : 0 , 
    "indexBounds" : { } , 
    "allPlans" : [ { "cursor" : "GeoSearchCursor" , "n" : 4 , "nscannedObjects" : 4 , "nscanned" : 4 , "indexBounds" : { } 
    } 

我使用的是mongodb版本2.4.4。

我在做什麼錯?你的答案是非常感謝。

+0

你存儲{緯度,經度}爲了你的指數在你的文檔結構建議? [2d索引的順序](http://docs.mongodb.org/manual/core/2d/)必須是{long,lat}。如果您可以包含您希望在$ near查詢中找到的一些樣本點,這將會很有幫助。 – Stennie

+0

正如你可以看到我的loc嵌入對象包括更多的屬性,然後經緯度,長和順序是lat,lon ..你認爲這會導致使用複合索引? –

+0

根據解釋,查詢**是**使用GeoSearchCursor(2d地理空間索引)。您需要以長,平經度順序獲得座標,否則地理位置查詢將無法按預期工作。這是2d索引唯一支持的順序。 – Stennie

回答

5

解釋輸出顯示「光標」:「GeoSearchCursor」。這表示您的查詢使用了地理空間索引。

詳見以下: http://docs.mongodb.org/manual/reference/method/cursor.explain/

2D索引支持一個複合索引只有一個附加的字段,作爲2D索引字段的後綴。 http://docs.mongodb.org/manual/applications/geospatial-indexes

由於@stennie在您的問題的評論中提到的問題可能是座標的順序。他們應該訂購長,拉特。如果這不起作用,請嘗試將loc存儲爲具有長第一個元素的數組,lat秒。

這裏是一個工作實例:

我創建位置3個簡檔對象作爲陣列和locTime從LOC分離。

> db.profile.find() 
{ "_id" : ObjectId("52cd54f1c43bb3a468b9fd0d"), "loc" : [ -6, 50 ], "age" : 29, "pid" : "001", "locTime" : NumberLong(0) } 
{ "_id" : ObjectId("52cd5507c43bb3a468b9fd0f"), "loc" : [ -6, 53 ], "age" : 30, "pid" : "002", "locTime" : NumberLong(1) } 
{ "_id" : ObjectId("52cd5515c43bb3a468b9fd10"), "loc" : [ -1, 51 ], "age" : 31, "pid" : "003", "loctime" : NumberLong(2) } 

查找使用大的距離和年齡

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 5}, "age" : { "$gte" : 0 , "$lte" : 33}}) 
{ "_id" : ObjectId("52cd5515c43bb3a468b9fd10"), "loc" : [ -1, 51 ], "age" : 31, "pid" : "003", "loctime" : NumberLong(2) } 
{ "_id" : ObjectId("52cd54f1c43bb3a468b9fd0d"), "loc" : [ -6, 50 ], "age" : 29, "pid" : "001", "locTime" : NumberLong(0) } 

的解釋示出了索引被用來:

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 5}, "age" : { "$gte" : 0 , "$lte" : 33}}).explain() 
{ 
    "cursor" : "GeoSearchCursor", 
    "isMultiKey" : false, 
    "n" : 2, 
    "nscannedObjects" : 2, 
    "nscanned" : 2, 
    "nscannedObjectsAllPlans" : 2, 
    "nscannedAllPlans" : 2, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 0, 
    "indexBounds" : { 

    }, 
} 

縮小與同年齡範圍

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 1}, "age" : { "$gte" : 0 , "$lte" : 33}}) 
的距離

這裏是展開AlN,再次使用索引:

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" :  1}, "age" : { "$gte" : 0 , "$lte" : 33}}).explain() 
{ 
    "cursor" : "GeoSearchCursor", 
    "isMultiKey" : false, 
    "n" : 1, 
    "nscannedObjects" : 1, 
    "nscanned" : 1, 
    "nscannedObjectsAllPlans" : 1, 
    "nscannedAllPlans" : 1, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 0, 
    "indexBounds" : { 

    }, 
} 

這裏有指標:

> db.profile.getIndices() 
[ 
    { 
     "v" : 1, 
     "key" : { 
      "_id" : 1 
     }, 
     "ns" : "test.profile", 
     "name" : "_id_" 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "loc" : "2d", 
      "age" : 1 
     }, 
     "ns" : "test.profile", 
     "name" : "loc_2d_age_1" 
    } 
] 
+0

您是否建議我不能在2d中使用複合索引?使用地理空間索引的查詢導致我在我的對象中的loc字段上有2d索引...我如何使用複合索引? –

+0

我已經更新了答案。您可以在2d中使用複合索引。 2d索引僅支持一個附加字段,作爲2d索引字段的後綴。 http://docs.mongodb.org/manual/applications/geospatial-indexes –