2014-12-07 120 views
1

概念上我想弄清楚的是,如果除了點符號之外還有一種替代方法可以用mongo訪問嵌套文檔。

我試圖做到:

我有一個用戶集合,每個用戶都有一個嵌套songVotes集合,其中該嵌套songVotes集合密鑰是songIds和價值是他們投票形成用戶-1,0或1.

我有一個「房間集合」,許多用戶去了,他們對每首歌曲的集體投票影響房間。單個房間還具有嵌套的songVotes集合,其中鍵爲歌曲標識,但是值是累計房間中所有用戶的累計投票總數。對於Meteor.js而言,當用戶進入房間將其投票添加到此嵌套累積投票集合時,其效率更高。 再次因爲Meteor.js中的被動連接不以任何有效的方式得到支持,所以打破這些嵌套集合來解決我的問題也沒有意義。

所以我遇到麻煩的是這個更新操作,當用戶第一次進入房間時,我將單個用戶嵌套的songVotes集合並使用mongo $ inc操作符將其應用於整個嵌套的累積songVotes集合房間。

問題是,如果您想在嵌套字段中使用$ inc運算符,則必須使用點符號來訪問它們。所以我在廣義上問的是,如果有一個很好的方式來將這樣的更新應用到嵌套對象。或許指定$ INC像一個全球性的點符號前綴:

var userVotes = db.collection.users.findOne('user_id').songVotes // userVotes --> { 'song1': 1, 'song2': -1 ... } db.rooms.update({ _id: 'blah' }, { $set: { roomSongVotes: { $inc: userVotes } } })

+0

不該」它就像update({_id:'blah'},{$ inc:{'roomSongVotes.userVotes':1}})。我認爲查詢的語法可能有問題,但我不確定爲什麼你需要點符號以外的東西。我認爲如果元素名稱不是常規變量名稱,那麼您可以使用[]中的元素名稱 – DAB 2014-12-07 02:39:22

+0

yes是的,但如果我有50個左右的字段,我想更新它們全部嵌套在同一父字段「songVotes」 ,那麼我不想指定「songVotes.blah1」,「songVotes.blah2」,... - 如果我不必。如果能夠不必使用點符號,並使用$ inc簡單地爲所有要影響的子字段指定一個父字段,那就太好了。有沒有辦法做到這一點? – mccormjt 2014-12-07 21:48:21

回答

1

你需要使用點符號,但你仍然可以做,在你的情況下,通過編程的方式構建了更新對象:

var userVotes = {'song1': 1, 'song2': -1}; 
var update = {$inc: {}}; 
for (var songId in userVotes) { 
    update.$inc['roomSongVotes.' + songId] = userVotes[songId]; 
} 
db.rooms.update({ _id: 'blah' }, update); 

這樣,update被建成爲:

{ '$inc': { 'roomSongVotes.song1': 1, 'roomSongVotes.song2': -1 } }