2016-05-26 50 views
1

說我有文檔的集合,每一個管理教師和學生之間的討論:有條件更新,視場匹配

{ 
    _id, 
    teacherId, 
    studentId, 
    teacherLastMessage, 
    studentLastMessage 
} 
有3個參數

我會得到查詢:一個_id,一個userIdmessage
我正在尋找一種方式來更新teacherLastMessage場或根據用戶是一個studentLastMessage場。

目前,我有這樣的:

return Promise.all([ 

    // if user is teacher, set teacherLastMessage 
    db.collection('discussions').findOneAndUpdate({ 
     teacherId: userId, 
     _id 
    }, { 
     $set: { 
      teacherLastMessage: message 
     } 
    }, { 
     returnOriginal: false 
    }), 

    // if user is student, set studentLastMessage 
    db.collection('discussions').findOneAndUpdate({ 
     studentId: userId, 
     _id 
    }, { 
     $set: { 
      studentLastMessage: message 
     } 
    }, { 
     returnOriginal: false 
    }) 


]).then((results) => { 
    results = results.filter((result) => result.value); 

    if (!results.length) { 
     throw new Error('No matching document'); 
    } 

    return results[0].value; 
}); 

有沒有辦法告訴蒙戈做出有條件更新,基於字段是否匹配?這樣的事情:

db.collection('discussions').findOneAndUpdate({ 
    $or: [{ 
     teacherId: userId 
    }, { 
     studentId: userId 
    }], 
    _id 
}, { 
    $set: { 
    // if field matched was studentId, set studentLastMessage 
    // if field matched was teacherId, set teacherLastMessage 
    } 
}); 

當然,它一定可以與mongo 3.2?

+1

這是不可能做到這一點使用只有一個查詢。你需要改變你的數據結構。爲教師和學生創建單獨的對象。這樣你就可以使用一個查詢來更新。 – Shrabanee

回答

1

你想將需要引用的$set內的其他領域是什麼。目前這是不可能的。以this ticket爲例。

首先,你目前有兩個更新查詢方法看起來就好了我。你可以繼續使用它,只要確保你有正確的索引。也就是說,要獲得這些更新的最佳性能,你應該有兩個複合索引:

  • { _id: 1, teacherId: 1 }
  • { _id: 1, studentId: 1 }

要從另一個角度來看待這個問題,您應該重組您的數據。例如:

{ 
    _id: '...', 
    users: [ 
     { 
      userId: '...', 
      userType: 'student', 
      lastMessage: 'lorem ipsum' 
     }, 
     { 
      userId: '...', 
      userType: 'teacher', 
      lastMessage: 'dolor sit amet' 
     } 
    ] 
} 

這將允許您使用單個查詢執行更新。

1

你的數據結構是有點不可思議,除非你有需要的成型這樣,我建議建立一個用戶類型,除非一個用戶都可以是一個老師和一個學生,然後讓你的結構數據的具體業務情況。

$set{} PARAM可以採取一個對象,我的建議是先做你的業務邏輯。如果更新是針對教師或學生的,您應該在更新之前知道 - 應設置某種變量/認證級別以區分教師和學生。也許在回調中成功登錄後,您可以設置cookie /本地存儲。無論如何 - 如果你有當前類型的用戶,那麼你可以更早地構建你的對象,所以根據用戶類型使用你需要的屬性來創建一個對象文本。 所以

if(student) 
{ 
    var updateObj = { studentLastMsg: msg } 
} 
else 
{ 
    var updateObj = { teacherLastMsg: msg } 
} 

在您的更新然後通過對$set{updateObj}我會讓這一個片段 - 在移動

+0

我的用戶可以是「學生」或「教師」因討論,並在某些情況下,我將無法辨別他們的角色之前,我更新文檔。因此,如果可能的話,我會去處理2個查詢或重組我的數據。 – seven11