2012-01-19 87 views
2

我有一個包含屬性如MongoDB的集合:如何有效地按位置和日期範圍搜索大型數據集?

longitude, latitude, start_date, end_date, price 

我有超過500萬份文件。

我的問題是如何儘可能有效地以緯度/經度,日期範圍和價格進行搜索?
在我看來我的選擇是:

  1. 創建於經/緯的地理空間索引長期使用MongoDB的鄰近搜索...然後根據日期範圍和價格過濾此。
    • 我還沒有測試這個,但是,我擔心如果我們每秒搜索一次左右,搜索數據量就會太大,無法快速搜索。
    • 您是否有過在這些情況下MongoDB會如何反應的經驗?
  2. 按位置將數據拆分爲多個集合。即通過諸如london_collection,paris_collection,new_york_collection之類的城市。
    • 然後,我需要先經緯度/緯度查詢,找到最近的城市集合,然後使用日期和價格過濾器對該集合中的子集數據執行MongoDB空間搜索。
    • 我會分配不均勻的文件,因爲有些城市會有比其他文件更多的文件。
  3. 按日期而不是位置創建集合。與上面相同,但每個文檔都根據日期範圍分配了一個集合。
    • 具有跨多個集合的日期範圍的搜索存在問題。
  4. 根據每個文檔的city_start_date_end_date創建唯一標識符。
    • 再次,我將不得不使用我的緯度/長查詢來查找最近的城市追加日期範圍來訪問密鑰。這似乎相當快,但我真的不喜歡城市查找方面......它似乎有點難看。

我與選項1)實驗的過程,但真的很想聽聽你的想法之前,我去太遠一個特定的路徑?

搜索引擎如何分割和管理他們的數據......這肯定是一個類似的問題?

另外我不必使用MongoDB,我打開其他選項?

非常感謝。

+0

如果您的索引正確,第一個解決方案肯定會與關係數據庫(mysql)一起工作。 – ElKamina

回答

2

索引和數據訪問性能是一個深刻且複雜的主題。很多因素都會影響最有效的解決方案,包括數據集的大小,讀寫比率,IO和後備存儲的相對性能等。

雖然我不能給你一個具體的答案,我可以建議調查使用morton數字作爲提取多個類似數值(如lat long)的有效方法。

Morton number

+0

優秀 - 這可能會非常有幫助。我會做一些調查。從我+1。 – emson

+1

這是很好的理論輸入。然而,據我所知,geohash是一個Z階曲線,這就是MongoDB用於其本地地理空間索引的內容。在數據庫頂部手動重新構建它並不是一個好主意。它也處理邊緣情況並提供大量搜索模式(多邊形,球形等)。由於MongoDB不支持按位查詢,因此目前可能無法實現這一點。 – mnemosyn

1

爲什麼你認爲選項1是太慢?這是真實世界測試的結果,還是這只是一個假設,它可能最終不會奏效?

MongoDB原生支持geohashing並將座標轉換爲單個數字,然後可以通過BTree遍歷進行搜索。這應該是相當快的。混淆多個集合對我來說似乎不是一個好主意。它所做的只是用數據庫中的一個BTree遍歷替換一些代碼,而這些代碼仍然需要編寫,測試和維護。

不要推倒重來,而是要設法優化最明顯的路徑(1)第一名:

  1. 建立地理指標
  2. 使用explain,以確保查詢實際使用索引
  3. 確保您的索引放入RAM
  4. 使用配置文件數據庫中的built-in profiler
  5. 在指標沒有一個茶不要測量一個「冷」系統的性能NCE去又
  6. 如果可能的RAM,如果可能,嘗試不使用geoNear,並堅持到較快(但不完美的球形)near查詢
  7. 如果你還在打的限制,看sharding分配讀並寫入多臺機器。
+0

非常感謝您的評論 - 正如我上面提到的,我還沒有測試過現實生活中的任何想法。但是我正在建立數據集。你肯定是對的,因爲標準應該首先遵循,只有當這不足以滿足期望時,才應該嘗試其他的東西。 – emson

+0

所有這些建議的其中一個見解是,它促使我重新思考數據的結構。具體來說,我將研究QuadTrees根據日期範圍生成一個id。這可以提供允許在日期上進行空間搜索的附加好處。我還會深入調查mongo空間搜索是如何工作的。非常感謝。 – emson

+0

日期空間搜索?四叉樹只有在至少有兩個維度時才起作用。四叉樹對於我認爲的一維數據沒有多大幫助,一維四叉樹*是一個BTree。還要注意,MongoId類型已經包含日期戳記,如果這是一個問題,它將改進數據局部性。 – mnemosyn