2011-04-12 130 views
2

所以我對mongoDb很新,所以我認爲這可能是對一般用法的誤解。所以忍受着我。 我有一個文件的架構我的工作因此mongoDB:重複值的唯一索引

{ 
    name: "bob", 
    email: "[email protected]", 
    logins: [ 
     { u: 'a', p: 'b', public_id: '123' }, 
     { u: 'x', p: 'y', public_id: 'abc' } 
    ] 
    } 

我的問題是,我需要確保公衆IDS是文檔和收藏中是唯一的, 此外,還有一些現有的記錄是從遷移一個沒有記錄的mySQL DB,因此將全部替換爲mongo中的null值。

我想它的任何一個指數

db.users.ensureIndex({logins.public_id: 1}, {unique: true}); 

這是不工作,因爲丟失的鑰匙,並拋出一個E11000 duplicate key error index:

或者這是一個更根本的問題的模式我不應該將對象嵌套到像這樣的數組結構中。在這種情況下,什麼?爲user_logins單獨收集?這似乎違背了嵌入式文檔的想法。

回答

0

感謝所有。最後,我選擇將其分成兩個集合,一個用於用戶,另一個用於登錄。 用戶來說,這看起來有點像..

userDocument = { 
     ... 
     logins: [ 
     DBRef('loginsCollection', loginDocument._id), 
     DBRef('loginsCollection', loginDocument2._id),  
     ] 
    } 

    loginDocument = { 
     ... 
     user: new DBRef('userCollection', userDocument ._id) 
    } 

雖然不是我原是後(單集)據工作niocely並利用MongoId uniquness有一個約束現已內置在數據庫級別和沒有在應用程序級別實現。

2

如果你希望üp有總是在每次插入相同的值(如在您的示例代碼段),您可能需要使用$addToSet操作上插入,以確保您的public_id領域的獨特性。否則,我覺得在整個系列中使它們與外部維護或js功能不兼容是非常困難的。

如果不是,我可能會將它們存儲在它們自己的集合中,並使用public_id作爲_id字段來確保它們在集合中的跨文檔唯一性。也許這與嵌入式文檔在doc數據庫中的想法相矛盾,但根據不同的要求,我認爲這可以忽略不計。

+0

不幸的是我worte錯誤。 [糾正],我需要這個工作插入和更新。我認爲$ addToSet只適用於更新。此外,它需要每個查詢而不是數據庫約束。 – Roon 2011-04-12 10:29:33

+0

@Roon:閱讀'upsert':http://www.mongodb。org/display/DOCS/Updating – 2011-04-12 10:39:04

+0

使用upsert條件也意味着進行更新,這可能有助於檢查在u和p不同的情況下,嵌套文檔中是否已存在public_id。我認爲沒有任何解決方案,除了將嵌套文檔存儲在其自己的集合中,並使用_id字段或替代索引將限制實施爲數據庫約束。 – proximus 2011-04-12 10:55:59

1

此外,還有一些現有的記錄正在從沒有記錄的mySQL DB遷移,因此將全部由mongo中的空值替換。

因此,您想要對不是真正唯一的數據集應用唯一索引。我認爲這只是一個建模問題。

如果logins.public_idnull那將違反您的唯一性約束,那麼就不要把它寫在所有:

{ 
    logins: [ 
     { u: 'a', p: 'b' }, 
     { u: 'x', p: 'y' } 
    ] 
    }