2017-10-09 87 views
0

這裏我有內部test.test收集兩個文件:Pymongo - 古怪的聚集行爲

> db.test.find() 
{ "_id" : ObjectId("AAA"), "last_updated" : 1000, "update_interval" : 50 } 
{ "_id" : ObjectId("BBB"), "last_updated" : 1200, "update_interval" : 50 } 

我想找到應該(通過測試last_updated <= now - update_interval表達)更新文件。

首先,我試圖用Python pymongo如下:

from pymongo import MongoClient 

db = MongoClient().test 

now = 1225 
r = db.test.find({ 
    'last_updated': {'$lte': {'$subtract': [now, '$update_interval']}} 
}) 
for item in r: 
    print(r) 

但是,它不顯示任何信息。但是當我將{'$subtract': [now, '$update_interval']}更改爲硬編碼值1175時,它工作正常。

我認爲我不能使用$subtract外聚集的管道,所以我嘗試另:

r = db.test.aggregate([ 
    { 
     '$match': { 
      'last_updated': {'$lte': {'$subtract': [now, '$update_interval']}}, 
     }, 
    }, 
]) 

嗯,它只是看起來與以前的一個,並且是它沒有工作過。

最後,我給了最後一次嘗試:

r = db.test.aggregate([ 
    { 
     '$project': { 
      'when_to_update': {'$subtract': [now, '$update_interval']}, 
      'last_updated': True, 
      'update_interval': True, 
     }, 
    }, 
    { 
     '$match': { 
      'last_updated': {'$lte': '$when_to_update'}, 
     }, 
    }, 
]) 

好吧,它不會再工作。但奇怪的是,當我剛剛獲得通過的$project管道,結果是這樣的:

{'_id': ObjectId('AAA'), 'last_updated': 1000.0, 'update_interval': 50.0, 'when_to_update': 1175.0} 
{'_id': ObjectId('BBB'), 'last_updated': 1200.0, 'update_interval': 50.0, 'when_to_update': 1175.0} 

所以應該通過$match管道太后工作!我錯過了什麼嗎?等待你的答案,謝謝。

+1

你不能比較比賽階段的領域。這是可能的3.6版本。簡單的解決方法是改變''can_update':{'$ lte':['$ last_updated', {'$ subtract':[now,'$ update_interval']}]}''和'{''''匹配':{ 'can_update':true, }, }' – Veeram

+0

[MongoDb查詢條件比較2個字段]的可能重複(https://stackoverflow.com/questions/4442453/mongodb-query-condition-on-比較2字段) – Veeram

回答

1

對,你不能在彙總管道外使用$減法。聚合投影運算符對聚合框架是唯一的。

目前,在$ match表達式中使用字段值是非常棘手的;在MongoDB 3.6中,新的$ expr操作符將有所幫助。同時試試這個:

now = 1225 
r = db.test.aggregate([ 
    { 
     '$project': { 
      'comparison': {'$cmp': [ 
       now, 
       [{'$sum': ['$update_interval', '$last_updated']}]]}, 
      'last_updated': True, 
      'update_interval': True 
     } 
    }, { 
     '$match': { 
      'comparison': -1 
     } 
    } 
]) 

for item in r: 
    print(item) 

在你的for-loop中,你必須打印「item」,而不是「r」。

+0

謝謝你的一個很好的建議。順便說一句,我已經找到了一種方法,通過'r = db.test.aggregate([{'$ addFields':{'when_to_update':{'$ add':['$ last_refreshed','$ interval']}} },{'$ match':{'when_to_update':{'$ lte':now}}}])'。而且,我想現在更新我的mongodb服務器到3.6 ... – hallazzang

+0

太棒了。 MongoDB 3.6將在幾個月後出來,同時你可以下載3.5.x開發版本:https://www.mongodb.com/download-center#development –