2016-11-25 89 views
4

目前我們在MongoDB 3.2.9$near操作中遇到了很大的麻煩。

問題是,創建遊標時會有無盡的負載 - 直到超時。這個問題只是在我們不使用$maxDistance時引起的 - 在我們的情況下,這個問題非常重要。

這是我們的集合:

位置

大約2.000.000文件與GeoJSON的財產 「幾何體」,這也被編入索引。

除了幾何外,還有另一個名爲「category」的索引。

在我們的特殊情況下,我們的查詢現在看起來是這樣的:

Locations.find({ 
    category: 'ABC', 
    geometry: { 
    '$near': { 
     $geometry: { 
     type: "Point" , 
     coordinates: [ 13.357315063476564, 52.53167855932515 ] 
     } 
    } 
    } 
}, { 
    limit: 10 
}); 

這個查詢將導致超時

爲了解決這個問題,我們需要添加$maxDistance操作,它會正常工作(如果$ maxDistance的價值不太高),但在我們的情況下,$maxDistance是非常糟糕的,因爲它不一樣,如果1點的位置關係與另一個人有很大的距離。例如,當第一個找到的位置在挪威,第二個位於澳大利亞的時候它可以。

另一個信息:

這個問題時,有LESS那麼結果的極限正義事業。在我們上面的例子中,在我們的數據庫中有8個這個類別的位置。如果我們在10個以上的位置執行相同的查詢,則需要大約幾個毫秒。

只是爲了總結這件事:我們正在使用MongoDB的3.2.9

// Does not work. Ends up in an timeout 
Locations.find({ 
    category: 'ABC', // has 9 locations 
    geometry: { 
    '$near': { 
     $geometry: { 
     type: "Point" , 
     coordinates: [ 13.357315063476564, 52.53167855932515 ] 
     } 
    } 
    } 
}, { 
    limit: 10 
}); 

// Works fine because of the $maxDistance - but in our case a $maxDistance is very BAD and needed to be prevented! 
Locations.find({ 
    category: 'ABC', // has 9 locations 
    geometry: { 
    '$near': { 
     $geometry: { 
     type: "Point" , 
     coordinates: [ 13.357315063476564, 52.53167855932515 ] 
     } 
    }, 
    '$maxDistance': 5000 // If this value is too high - like the maxDistance is "the whole world" the query would also end up in an timeout 
    } 
}, { 
    limit: 10 
}); 

// Works fine because >= 10 items 
Locations.find({ 
    category: 'DEF', // has 10 locations 
    geometry: { 
    '$near': { 
     $geometry: { 
     type: "Point" , 
     coordinates: [ 13.357315063476564, 52.53167855932515 ] 
     } 
    } 
    } 
}, { 
    limit: 10 
}); 

附加信息

這個問題無關的事實是,我們是在nodeJS中使用MongoDB。我們也使用RoboMongo,當執行這個查詢時,同樣的問題會導致:超時!

+0

也許你需要爲'$ maxDistance'的值使用'Number.POSITIVE_INFINITY'。用2000002文件完美地工作 – styvane

+0

很遺憾,這對我們不起作用。通過這個查詢也會以超時結束。 – TJR

+0

什麼是您使用的Mongo驅動程序? – Khang

回答

1

我創建了一個集合,因爲您擁有包含200萬個帶有隨機數據的文檔,準備了categorygeometry字段的索引。當我繼續測試這個系列時,我遇到了和你一樣的問題。

花了大約50秒沒有$maxDistance價值。起初這似乎是合理的,因爲沒有$maxDistance蒙戈必須搜索「世界各地」的結果。但後來我檢查了查詢結果.explain(),發現它根本沒有使用索引,查詢中沒有階段IXSCAN(在舊版本的Mongo中是BasicCursor)。所以問題很明顯,我錯誤地創建了索引,你也是。

您(我也是)創建的索引是Single Field Indexes,這隻有在單個字段進行搜索時纔有用。在這種情況下,您通過兩個字段進行搜索,因此您需要使用Compound Indexes。使用該命令來創建,其可以在搜索中使用的化合物索引:

db.collection({category: 1, geometry: '2dsphere'}); 

我這樣做,並且結果是驚人的,時間爲50秒降低到幾百毫秒。

相關問題