2013-11-26 51 views
0

我是從關係數據庫MongoDB的改變墊層數據庫的過程中,我需要「重建」通過MongoDB的查詢相同的語義。總而言之,這是怎麼回事微細,爲一兩件事例外:SQL最大()函數:的MongoDB相當於SQL的最大()

SELECT * FROM my_table 
WHERE (GREATEST(FIELD_A, FIELD_B, FIELD_C, FIELD_D) 
BETWEEN some_value AND some_value) 
AND FIELD_E = another_value; 

我似乎無法找到一個相當於這個GREATEST()函數。我知道可以通過使用$ cond操作符來實現類似的功能,但由於GREATEST()函數在找到4個值中的最大值,所以這將是很多條件。有沒有其他的方式來實現這一點?我查看了聚合框架和mapReduce,但我似乎無法在聚合框架中找到任何直接相似的東西,並且我很難理解mapReduce框架。

這甚至有可能實現嗎?我會假設答案是肯定的,但我似乎無法找到合理的等效方式。

+0

應當注意的是,最大的不是SQL運算符但實際上是一個oracle運算符,它不是標準的 – Sammaye

+0

@Sammaye你在這裏絕對正確。然而,儘管最大()不是標準的一部分,但關係數據庫從我頭頂開始支持它(oracle,mysql,postgresql,sqlite(儘管在名字MAX下))是很常見的。 – Bendik

+0

這兩者並不完全相同,但是獲得最大值的簡單方法是對字段中的結果DESC進行排序 – Sammaye

回答

-2

的MongoDB目前不具備相當於GREATEST功能。你可以使用MapReduce,但它不會提供有效的立即結果。此外,您將無法有效地返回文檔的其他字段。您需要執行多個查詢,或者可能會複製所有數據。而且,如果不對結果進行更新處理,它將不會隨着文檔的修改而更新,因爲MongoDb中的Map Reduce必須手動啓動。

MongoDB的聚合框架的目的不是爲這種模式,如果可能的話,將導致一個非常漫長的管道。此外,它目前僅限於16MB的結果,並且不會輕易超過您彙總的字段。返回select *需要手動投影,可能不止一次,具體取決於所需的輸出。

既然要返回多個字段,結果不是聚集,我建議做一些簡單得多:

預先計算的greatest函數調用的結果,並將其存儲在文件作爲一個新的領域,便於在各種查詢中訪問。

+0

,但是你可以用MR和agg框架來完成這個工作,並且可能通過定期查找。 –

+0

當然,MR可以工作,但這似乎不必要的複雜和低效。雖然人們可以通過一系列複雜的聚合步驟來實現,特別是如果字段數量增加的話,我也不會推薦它。如果任何需要返回整個文檔而不僅僅是一個聚合,那麼他們真的沒有發揮MongoDb的優勢(因爲兩者都設計爲返回值和字段的集合,而不是'select *')。這與一個'find'。字段不能交叉比較,如'最大'所要求的。 – WiredPrairie

+0

請留下評論你爲什麼投票。 – WiredPrairie

1

如果查詢你報的是你要複製的東西,你可以採取不同的路線......

你想找到的所有文件的範圍(以及其他標準)之間的最大4個值。

可以改寫此爲所有4個值低於上限和至少一個高於低的文件。 東西沿着線:

find(
    {field_a:{$lt:some_upper_limit} 
    ,field_b:{$lt:some_upper_limit} 
    ,field_c:{$lt:some_upper_limit} 
    ,field_d:{$lt:some_upper_limit} 
    ,$or: 
     [{field_a:{$gt:some_lower_limit}} 
     ,{field_b:{$gt:some_lower_limit}} 
     ,{field_c:{$gt:some_lower_limit}} 
     ,{field_d:{$gt:some_lower_limit}} 
     ] 
    }) 

可能是一個好主意,看看指標如何可能有助於使這一有效,取決於數據,等等

+0

難道你不想比較每個領域的上下都一起否則可能會有某種組合,其中一個字段滿足一個條件而另一個不同於另一個條件,那麼它在技術上不會與原始查詢相同 –

+0

條件狀態不是關於單個字段(A,B,C或D)在邊界之間,它是關於最大的,關鍵是標準是所有這些必須低於上限(最大需要),並且任何超過下限(這將包括在超過1的情況下最大)。否則說,當且僅當所有值低於上限並且任何值高於下限時,最大值纔會在界限內... –