2015-01-26 72 views
0

如何在使用MongoDB的查詢中包含字段操作?Mongodb:將字段作爲查詢操作的結果

我的文檔包含'start_time'和'duration'字段,我希望獲取所有樣式活動的文檔(其中'now'低於'start_time'+'duration')。

PostgreSQL的當量是:

SELECT * FROM my_table 
    WHERE start_time + (INTERVAL '1 min' * duration)) > current_timestamp 

是否可以用一個簡單的查詢MongoDB中還是應該使用聚合管道來獲得相同的結果呢?

謝謝。

回答

1

假設current_timestamp這裏是一個外部變量,那麼這甚至不是在SQL中表示這種方法的好方法。

正確的方法是執行「反向」操作,而不是使數據庫重新計算「start_time」值,通過減去持續時間來改變輸入值的間隔,並使數據庫搜索「索引爲」值「」大於「」的時間搜索。

因此,您應該如何使用MongoDB來做到這一點,並用JavaScript代替所選語言。容易理解:

var duration = 5; // 5 minutes 
var current_timestamp = new Date(); 

var altered_time = new Date( 
    current_timetamp.valueOf() - (1000 * 60 * duration) 
); 

db.collection.find({ "start_time": { "$gt": altered_time } }) 

因此,與SQL表單一樣,執行比較是最理想的方式。

對於瘋了,或者如果你真的需要一個文檔中比較兩個字段,則非最佳的方式來做到這一點是與聚合管道也不能使用索引來解決這個問題:

db.collection.aggregate([ 
    { "$project": { 
     "doc": "$$ROOT", 
     "matched": { 
      "$gt": [ 
       { "$add": [ 
        { "$subtract": [ "$start_time", new Date("1970-01-01") ] }, 
        1000 * 60 * duration 
       ]}, 
       current_timestamp.valueOf() 
      ] 
     } 
    }}, 
    { "$match": { "matched": true } } 
]) 

不是一個很好的方法來做到這一點,但是你寫的SQL也不是。


那麼,持續時間是在當前文檔中的字段,那麼就應對不同:

db.collection.aggregate([ 
    { "$project": { 
     "doc": "$$ROOT", 
     "matched": { 
      "$gt": [ 
       { "$add": [ 
        { "$subtract": [ "$start_time", new Date("1970-01-01") ] }, 
        { "$multiply": [ 1000 * 60, "$duration" ] } 
       ]}, 
       current_timestamp.valueOf() 
      ] 
     } 
    }}, 
    { "$match": { "matched": true } } 
]) 
+0

您的解決方案不符合我的要求:「時間」不是一個全局變量,而是一個字段對於每條記錄是不同的。 – 2015-01-27 09:05:57

+0

@Cédric然後在字段名稱和日期數據之間插入變量,這正是我所說的。這並不理想,但SQL也不是。 BTW。當我出現時,Downvote就在這裏,但這就是你將發佈「轉置我的SQL」而不顯示一些嘗試嘗試某些東西的東西。僅供將來參考。 – 2015-01-27 11:19:45

+0

我知道我的方法並不理想,但它是作出概念驗證和了解MongoDB的第一步。感謝您的建議。你是對的:映射SQL邏輯不是最終的,而只是我的遷移過程中的一步。接下來的步驟是真正整合no-sql的精神。 – 2015-01-27 22:02:43