我正在关注此文件
和
http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html
当我保存我的文档时,我有两个收藏
像这样: {
"_id" : ObjectId("5458e370d16fb63f250041a7"),
"name" : "A Foo Bar",
"price" : 19.99,
"posts" : [
{
"$ref" : "Embedd",
"$id" : ObjectId("5458e370d16fb63f250041a8"),
"$db" : "test_database"
}
]
}
我想要
{
"_id" : ObjectId("5458e370d16fb63f250041a7"),
"name" : "A Foo Bar",
"price" : 19.99,
"posts" : [
{
"mycomment" :"dsdsds"
" date" : date
}
]
}
我希望对数据进行非规范化。我该怎么办?
我可以使用mongoDb的$ push,$ addToSet等方法吗?
由于
答案 0 :(得分:7)
Doctrine ODM支持references和embedded documents。
在您的第一个示例中,您正在使用引用。主文档(假设它叫做Product)引用了许多Post文档。那些Post文档存在于他们自己的集合中(出于某种原因,这被命名为Embedd
- 如果你保留这个模式,我建议重命名)。默认情况下,ODM使用DBRef约定作为引用,因此每个引用本身都是一个包含$ref
,$id
和$db
字段的小型嵌入式文档。
可以通过使用嵌入式文档(在您的案例中使用@EmbedMany
映射)来实现非规范化。如果您要嵌入Post文档,则Post类应映射为@EmbeddedDocument
。这告诉ODM它不是一流的文档(属于它自己的集合),因此它不必担心_id
之类的跟踪它(事实上,嵌入式文档甚至不需要标识符,除非你想映射一个)。
我决定嵌入或引用的经验法则一般都在问自己:“我是否需要在父文档的上下文之外使用此文档?”如果邮政在产品记录之外没有身份,我很乐意将其嵌入;但是,如果我后来发现我的应用程序还想向用户显示他们所有帖子的列表,或者我需要通过帖子查询(例如所有最近帖子的提要,不论产品如何),那么我可能想参考帖子集合中的文档(或根据需要简单地复制嵌入的帖子)。
或者,您可以决定帖子应该存在于他们自己的集合中和嵌入到Product上。在这种情况下,您可以将AbstractPost类创建为@MappedSuperclass
并在那里定义公共字段。然后,使用Post和EmbeddedPost子类(相应地映射)扩展它。您将负责创建一些代码以从Post文档生成EmbeddedPost,这将适合嵌入Product.posts
数组。此外,您需要处理顶级帖子和嵌入式帖子之间的数据同步(例如,如果有人编辑帖子评论,您可能也希望更新所有相应的嵌入式版本。)
关于引用主题:ODM还支持引用映射的simple
选项,在这种情况下,它只存储引用文档的_id
而不是更大的DBRef对象。在大多数情况下,让DBRef存储每个引用文档的集合和数据库名称 是非常多余的;但是,如果您正在使用single-collection inheritance,则DBRef实际上很有用,因为ODM使用该对象来存储额外的鉴别器信息(即引用对象的类)。