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

mon*_*ser 3 doctrine mongodb symfony doctrine-orm

我正在关注这个文件

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

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"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我想要

   {
    "_id" : ObjectId("5458e370d16fb63f250041a7"),
    "name" : "A Foo Bar",
    "price" : 19.99,
    "posts" : [ 
        {
           "mycomment" :"dsdsds"
           " date" : date
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我想要对我的数据进行非规范化.我该怎么做?

我可以使用像mongoDb的$ push,$ addToSet等方法吗?

谢谢

jmi*_*ola 7

Doctrine ODM支持引用嵌入式文档.

在您的第一个示例中,您正在使用引用.主文档(假设它叫做Product)引用了许多Post文档.那些Post文档存在于他们自己的集合中(出于某种原因,这被命名Embedd- 如果你保留这个模式,我建议重命名).默认情况下,ODM使用DBREF为引用约定.因此,每个引用是本身有一个小型的嵌入式文件$ref,$id以及$db多个领域.

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

我决定嵌入或引用的经验法则一般都在问自己:"我是否需要在父文档的上下文之外使用这个文档?" 如果邮政在产品记录之外没有身份,我很乐意将其嵌入; 但是,如果我后来发现我的应用程序还想向用户显示他们所有帖子的列表,或者我需要按帖子查询(例如所有最近帖子的提要,不论产品如何),那么我可能想参考帖子集合中的文档(或根据需要简单地复制嵌入的帖子).

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


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