如何在mongodb中级联删除文档?

Posted

技术标签:

【中文标题】如何在mongodb中级联删除文档?【英文标题】:How to cascade delete document in mongodb? 【发布时间】:2019-02-08 10:12:43 【问题描述】:

我在 Mongodb 中有用户和照片文档。每张照片都属于用户,并且可以在用户之间共享一张照片。假设 user1 有 p1、p2、p3 照片,而 user2 有 p3、p4、p5 照片。如果我删除 user1(手动使用 Compass 等工具),p1 和 p2 也应该被删除,而不是 p3。如何实现,需要定义什么样的数据库结构?

目前,如果我删除 user1,则不会删除任何照片并保留在数据库中,这会导致从使用数据库的应用程序的角度来看数据库已损坏。

它的 Spring Boot 应用和 User 和 Photo 声明为:

import lombok.Builder;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
@Data
@Builder
public class User 

    @Id
    private String id;


    @DBRef
    private Set<Photo> photos;


    private String name;


@Document
@Data
@Builder
public class Photo 

    @Id
    private String id;


    private String fileName;


【问题讨论】:

你必须这样做manually 不支持它。类似的答案是here 【参考方案1】:

正如 m4gic 和他链接的问题(here 和 here)所提到的,MongoDB 不支持级联删除。在您的情况下,您可能应该在 User 对象中创建一个数组,并将完整的子文档放入该数组中,而不是将它们保存在自己的集合中。这样,它们将与父级一起被删除,因为它们是其中的一部分。

【讨论】:

请记住,最大 BSON 文档大小为 16 兆字节【参考方案2】:

MongoDB 目前不支持级联删除。由于您已经将参考照片存储在 User 模型中,因此您可以从参考列表中获取照片 ID 并将照片一起删除。或者,您可以将照片数组嵌入到用户对象中,而不是将照片存储在单独的集合中。

您也可以参考此链接: What is the recommended equivalent of cascaded delete in MongoDB for N:M relationships?

【讨论】:

【参考方案3】:

@mindcraft 是对的,但是如果您想将照片保存在单独的集合中,那么您可以将访问属性添加到 photo 文档中,例如


  ref: 'https://....',
  access:[user1._id, user2._id]


然后你可以像这样查询 -

db.photos.find(access:$in:[user1._id])

虽然专门为照片单独收集不会有太大帮助。而是尝试将照片网址放入数组中

【讨论】:

以上是关于如何在mongodb中级联删除文档?的主要内容,如果未能解决你的问题,请参考以下文章

sql中级联删除,级联更新是怎么理解的?

SQLite“在删除级联时”不在Qt中级联

对于 N:M 关系,在 MongoDB 中推荐的级联删除等效项是啥?

首先在实体框架数据库中级联删除

Django级联删除反向外键

如何理解access设置中的“级联更新”和“级联删除”?