MongoDb Doctrine Symfony 2中的去规范化数据2



我正在跟踪此文档

http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/tutorials/getting-started.html

http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html

当我保存我的文档时,我有两个Collection

像这样:

   {
    "_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等方法吗?

感谢

Doctrine ODM同时支持引用和嵌入文档。

在第一个示例中,您使用的是引用。主文档(假设它被称为Product)引用了许多Post文档。这些Post文档存在于它们自己的集合中(出于某种原因,它被命名为Embedd——如果您保留此模式,我建议重命名它)。默认情况下,ODM对引用使用DBRef约定,因此每个引用本身就是一个包含$ref$id$db字段的小型嵌入文档。

反规范化可以通过使用嵌入文档(在您的情况下是@EmbedMany映射)来实现。如果要嵌入Post文档,Post类应该映射为@EmbeddedDocument。这告诉ODM它不是一个一流的文档(属于它自己的集合),所以它不必担心通过_id等来跟踪它(事实上,嵌入式文档甚至不需要标识符,除非你想映射一个标识符)。

我决定嵌入或引用的经验法则通常是问自己,"我需要在父文档的上下文之外的这个文档吗?"如果帖子在产品记录之外没有身份,我可以放心地嵌入它;然而,如果我后来发现我的应用程序还想向用户显示他们所有帖子的列表,或者我需要按帖子查询(例如,所有最近帖子的提要,与产品无关),那么我可能想引用帖子集合中的文档(或者根据需要简单地复制嵌入的帖子)。

或者,您可以决定帖子应该同时存在于自己的集合中,并且应该嵌入到产品中。在这种情况下,您可以创建一个AbstractPost类作为@MappedSuperclass,并在那里定义公共字段。然后,使用Post和EmbeddedPost子类(相应地映射)对其进行扩展。您将负责创建一些代码,以便从Post文档生成EmbeddedPost,该代码适合嵌入到Product.posts数组中。此外,您还需要处理顶级帖子和嵌入帖子之间的数据同步(例如,如果有人编辑帖子评论,您可能也希望更新所有相应的嵌入版本)。


关于引用:ODM还支持引用映射的simple选项,在这种情况下,它只存储引用文档的_id,而不是更大的DBRef对象。在大多数情况下,让DBRef为每个引用的文档存储集合和数据库名称是非常多余的;然而,如果使用单集合继承,DBRef实际上是有用的,因为ODM使用对象来存储额外的鉴别器信息(即被引用对象的类)。

最新更新