2012-08-30 29 views
4

我想加快對我的mongoDB的查詢,該查詢使用$ where來比較文檔中的兩個字段,這似乎是真的慢。如何將字段添加到包含兩個其他字段的比較結果的文檔中

我的查詢是這樣的:

db.mycollection.find({ $where : "this.lastCheckDate < this.modificationDate}) 

我希望做的是一個字段添加到我的文檔,即isCheckDateLowerThenModDate,關於這一點我可以執行一個可能更快速的查詢:

db.mycollection.find({"isCheckDateLowerThenModDate":true}) 

我很新的mongoDB一個不知道如何做到這一點。我將不勝感激,如果有人能夠給我一些提示或實例上

  1. 如何初始化對現有集合
  2. 如何保持這一領域的這樣一個領域。這意味着當lastCheckDatemodificationDate更改時如何更新此字段。

在此先感謝您的幫助!

回答

1

你在想一個正確的方式!

1.如何初始化現有集合上的這種字段。

最簡單的方法是加載每個文件(從你的語言),計算這個字段,更新和保存。

或者你可以通過蒙戈外殼進行更新:

db.mycollection.find().forEach(function(doc) { 
    if(doc.lastCheckDate < doc.modificationDate) 
    { 
    doc.isCheckDateLowerThenModDate = true; 
    } 
    else 
    { 
    doc.isCheckDateLowerThenModDate = false; 
    } 
    db.mycollection.save(doc); 
}); 

2.How保持這一領域。這意味着當 lastCheckDate或modificationDate更改時如何更新此字段。

你必須從你的客戶端代碼自己做。爲每次更新,保存操作和重新計算此值創建一些包裝。爲了確保這個更新能夠工作 - 編寫單元測試。

1

$where clause比較慢,因爲它使用JavaScript解釋器評估每個文檔。

有幾個備選方案:

1)假設你的使用情況是「尋找需要更新記錄」,採取的sparse index優勢:

  • 添加一個布爾場像needsChecking$set每當modificationDate更新時

  • 在您的「檢查」過程中,找到具有此字段集的文檔(由於稀疏索引應該快速)

    db.mycollection。找到({ 'needsChecking':真});

  • 你做了什麼後檢查是必要的,$unsetneedsChecking領域。

2)MongoDB 2.2中新增(更快)的功能是Aggregation Framework

這裏是增加一個「isUpdated」字段基於日期的比較,然後過濾匹配的文檔的一個例子:

db.mycollection.aggregate(
      { $project: { 
        _id: 1, 
        name: 1, 
        type: 1, 
        modificationDate: 1, 
        lastCheckDate: 1, 
        isUpdated: { $gt:["$modificationDate","$lastCheckDate"] } 
      }}, 
      { $match : { 
        isUpdated : true, 
      }} 
    ) 

使用聚合框架的一些當前限制條件是:

  • 您必須指定要包含的字段_id
  • 結果僅限於當前最大BSON文檔大小(MongoDB 2.2中的16Mb)
+0

問題是這樣給了他新的文檔和結果 - 它不會將新的計算字段保留到原始文檔中。 –

+0

確實如此,它取決於計算的字段是否需要保留或者只是查找某些記錄所需的瞬態值。我確實假設後者。 – Stennie

相關問題