2013-07-29 51 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