2013-07-29 55 views
0

我需要強制執行唯一約束上的嵌套文件,例如MongoDB的確保指數:嵌套重複實體

urlEntities: [ 
{ "url" : "http://t.co/ujBNNRWb0y" , "display_url" : "bit.ly/11JyiVp" , "expanded_url" : 
"http://bit.ly/11JyiVp"} , 
{ "url" : "http://t.co/DeL6RiP8KR" , "display_url" : "ow.ly/i/2HC9x" , 
"expanded_url" : "http://ow.ly/i/2HC9x"} 
] 

URL,DISPLAY_URL和expaned_url需要是唯一的。如何在MongoDB中爲這種情況發出ensureIndex命令?

另外,這樣的嵌套文件是否是一個好的設計,或者我應該將它們移動到一個單獨的集合,並從這裏引用它們在urlEntities裏面?我是MongoDB的新手,任何最佳實踐建議都會非常有幫助。

全部場景:

說,如果我在其中有幾百萬個數據的數據庫下面有一個文件:

{ 「_id」:{ 「$ OID」: 「51f72afa3893686e0c406e19」}, 「user」:「test」,「urlEntities」:[{「url」:「http://t.co/64HBcYmn9g」,「display_url」:「ow.ly/nqlkP」,「expanded_url」:「http://ow.ly/nqlkP」}],「count」:0}

當我得到另一個具有類似urlEntities對象的文檔時,我只需要更新用戶和計數字段。首先,我想對urlEntities字段執行唯一約束,然後處理異常,然後進行更新,否則,如果在插入前檢查每個條目是否存在,它將對性能產生重大影響。那麼,我該如何在urlEntities中強制執行唯一性呢?我試過

{"urlEntities.display_url":1,"urlEntities.expanded_url":1},{unique:true} 

但仍然能夠插入相同的文件兩次沒有例外。

此外,請建議任何更好的方法來處理這種情況。

謝謝。

+0

你看了關於['$ addToSet'(http://docs.mongodb.org/manual/reference/operator/addToSet/)運營商? –

+0

子文檔索引:http://stackoverflow.com/questions/16769705/subdocument-index-in-mongo – WiredPrairie

+0

好的設計?真的很難知道給出這麼少的信息。有很多可能性 - 這取決於你需要的查詢等。 – WiredPrairie

回答

0

嵌套文檔索引讀取this

關於第二部分(嵌套文檔最佳實踐) - 它確實取決於您的業務邏輯和查詢。如果這些嵌套文檔與第一類實體無關,這意味着您不會直接搜索它們,而只是在其父文檔的上下文中進行搜索,然後讓它們嵌套是有意義的。否則你應該考慮提取出來。

我認爲你的問題沒有絕對的答案。閱讀有關索引的章節......它幫助了我很多。

+0

我試過db.collection.ensureIndex({urlEntities.url:1,urlEntities.display_url:1,expanded_url = 1}),但它會拋出「語法錯誤, 意外的標記 。」另外,我可以確保索引當我的收藏是空的?比如在創建表時,我們如何在關係數據庫的表單中添加唯一約束? – popcoder

+0

閱讀@ Derick的評論... – pl47ypus

1

唯一性只是強制執行文件。你不能防止以下(從例如簡化):

db.collection.ensureIndex({ 'urlEntities.url' : 1 }); 
db.col.insert({ 
    _id: 42, 
    urlEntities: [ 
     { 
      "url" : "http://t.co/ujBNNRWb0y" 
     }, 
     { 
      "url" : "http://t.co/ujBNNRWb0y" 
     } 
    ] 
}); 

相若方式,你將有嵌套文檔的複合唯一鍵同樣的問題。

什麼你可以做的是以下幾點:

db.collection.insert({ 
    _id: 43, 
    title: "This is an example", 
}); 
db.collection.update( 
    { _id: 43 }, 
    { 
     '$addToSet': { 
      urlEntities: { 
       "url" : "http://t.co/ujBNNRWb0y" , 
       "display_url" : "bit.ly/11JyiVp" , 
       "expanded_url" : "http://bit.ly/11JyiVp" 
      } 
     } 
    } 
); 

現在你有一個_id 43一個urlEntities文檔的文檔。如果再次運行相同的更新查詢再次,它會不是添加一個新的數組元素,因爲完整組合url,display_url和expanded_url已經存在。

而且,看看在$addToSet查詢經營者的例子:http://docs.mongodb.org/manual/reference/operator/addToSet/

+0

在閱讀完您的答案後,我已經用完整的方案更新了我的問題。您提供的第一個例子不適用於我的要求。通過第二個例子,我不知道我如何處理文檔級插入。請檢查完整場景。 – popcoder

+0

第一個例子就是爲了說明**每個文檔**而不是**嵌套數組中**元素的唯一性,並且非常適用於您的案例。 – Derick

+0

Derick,單個文檔在urlEntities數組中不會有重複的條目。對於不同的文檔,這僅適用於我的情況。正如你所提到的那樣,每個文檔都可以強制實現唯一性,那麼你能否就如何在不同文檔中的urlEntities數組之間強制實現唯一性提供建議? – popcoder