簡體   English   中英

如何在MongoDB中刪除文檔和所有嵌入式文檔?

[英]How to remove document and all embedded documents in MongoDB?

我在Mongoose中定義了以下架構:

var postSchema = mongoose.Schema({
  title: String,
  body: String,
  created: Date,
  photos: Array
});

var Post = mongoose.model('Post', postSchema);

var photoSchema = mongoose.Schema({
  filename: String,
  mimetype: String,
  data: Buffer,
  created: Date
});

var Photo = mongoose.model('Photo', photoSchema);

如果我刪除Post ,我也希望所有相關的Photo也要刪除(例如在SQL中級聯刪除)。

如果我執行Post.remove({ _id: MY_POST_ID }) ,則僅刪除Post ,並且我的孤兒Photo留在數據庫中。

另外,我應該以某種方式在“ Photo架構中定義帖子ID嗎?

獲得真正原子操作的唯一方法是實際使用嵌入式模型,如下所示:

var photoSchema = mongoose.Schema({
  filename: String,
  mimetype: String,
  data: Buffer,
  created: Date
});

var postSchema = mongoose.Schema({
  title: String,
  body: String,
  created: Date,
  photos: [photoSchema]
});

var Post = mongoose.model('Post', postSchema);

然后,您實際上可以使用一個簡單的語句刪除所有內容,因為它們都在同一集合中,並且實際上在同一文檔中:

Post.remove({ "_id": postId },function(err) {
   // handling in here
});

使用當前架構,您將需要單獨刪除所有文檔:

var async = require("async");

var photoSchema = mongoose.Schema({
  filename: String,
  mimetype: String,
  data: Buffer,
  created: Date
});

var Photo = mongoose.model('Photo', photoSchema);

var postSchema = mongoose.Schema({
  title: String,
  body: String,
  created: Date,
  photos: [{ "type": Schema.types.ObjectId, "ref": "Photo" }]
});

var Post = mongoose.model('Post', postSchema);

// later

async.waterfall(
    [
        function(callback) {
            Post.findById(postId,callback);
        },

        function(post,callback) {
            Photo.remove({ "_id": { "$in": post.photos } },function(err) {
               if (err) callback(err);
               callback();
            });
        },

        function(callback) {
            Post.remove(photoId,callback);
        }
    ],
    function(err) {
       if (err); // do something
       // Job done
    }
)

如果您想避免先閱讀文檔,那么您可以

var photoSchema = mongoose.Schema({
  postId: Schema.types.ObjectId,
  filename: String,
  mimetype: String,
  data: Buffer,
  created: Date
});

然后刪除與“帖子”相關的所有“照片”,然后發出:

Photo.remove({ "postId": postId },function(err) {
   // removed or err
});

一般而言,如果您始終希望這種行為,並且帶有所有嵌入的“照片”信息的“發布”文檔不能增長到16MB以上,則嵌入選項最有意義,因為您實際上不需要使用“照片”除了單親的孩子之外,其他任何地方。

如果添加的照片僅屬於一個Post ,則可以將所有照片嵌入Post模式中。 您可以通過在Post模式中將照片對象推送到photos數組來實現。 然后,您的Post文檔將具有以下結構:

{
    title: 'My-first-post',
    body: 'Lorem ipsum',
    created: '01-01-1900',
    photos: [
        { filename: 'file1', mimetype: 'type', data: 238947289347239874, created: '01-02-1900' },
        { filename: 'file2', mimetype: 'type', data: 238947284321225671, created: '02-02-1900' }
    ]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM