0

我需要对嵌套文档强制执行唯一约束,例如:

网址实体:[
{ “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需要是唯一的。如何ensureIndex在 MongoDB 中针对这种情况发出命令?

此外,拥有这样的嵌套文档是一个好的设计,还是我应该将它们移动到一个单独的集合并从这里引用它们urlEntities?我是 MongoDB 的新手,任何最佳实践建议都会很有帮助。

完整场景:

假设我在包含数百万数据的数据库中有如下文档:

{“_id”:{“$oid”:“51f72afa3893686e0c406e19”},“用户”:“测试”,“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}

但是我仍然可以毫无例外地两次插入同一个文档。

4

2 回答 2

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 和 expand_url 的完整组合已经存在。

另外,请查看$addToSet查询运算符的示例:http ://docs.mongodb.org/manual/reference/operator/addToSet/

于 2013-07-30T08:32:25.850 回答
0

对于嵌套文档的索引,请阅读

关于第二部分(嵌套文档最佳实践) - 这实际上取决于您的业务逻辑和查询。如果这些嵌套文档作为第一类实体没有意义,这意味着您不会直接搜索它们,而只能在其父文档的上下文中搜索它们,那么让它们嵌套是有意义的。否则你应该考虑将它们提取出来。

我认为你的问题没有绝对的答案。阅读有关索引的章节......它对我有很大帮助。

于 2013-07-29T19:20:41.313 回答