Làm cách nào để xóa tài liệu bằng Node.js Mongoose?


291
FBFriendModel.find({
    id: 333
}, function (err, docs) {
    docs.remove(); //Remove all the documents that match!
});

Ở trên dường như không hoạt động. Các hồ sơ vẫn còn đó.

Ai đó có thể sửa chữa?

Câu trả lời:


489

Nếu bạn không cảm thấy muốn lặp lại, hãy thử FBFriendModel.find({ id:333 }).remove( callback );hoặcFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.findtrả về một Truy vấn , có removechức năng .

Cập nhật cho Mongoose v5.5.3 - remove()hiện không được chấp nhận. Sử dụng deleteOne(), deleteMany()hoặcfindOneAndDelete() instead.


3
Điều này có chạy phần mềm trung gian trước / sau loại bỏ? (một số phương pháp mô hình bỏ qua phần mềm trung gian tài liệu và tôi không chắc đây có phải là một trong số chúng không, tài liệu không rõ ràng)
hunterloftis

12
Tôi cho rằng @hunterloftis đã tìm ra điều này rồi, nhưng đối với bất kỳ ai khác đọc câu trả lời là không, điều này sẽ không chạy phần mềm trung gian trước / sau trên các tài liệu riêng lẻ.
số1311407

Điều này có vẻ như nhiều câu trả lời khác đề cập đến .exec()tuy nhiên điều này hoàn toàn không. Có .exec()cần thiết, có tác dụng phụ để sử dụng nó hay không?
DanH

Các tài liệu rõ ràng (có thể chúng đã được cập nhật) rằng điều này bỏ qua phần mềm trung gian - xem phần dưới cùng của mongoosejs.com/docs/middleware.html - vì vậy hãy cẩn thận, sử dụng phương pháp này có thể gây ra sự cố nghiêm trọng, khó theo dõi.
Jed Watson

1
câu trả lời chính xác! các đối số của cuộc gọi lại là gì?
k88074

299

CẬP NHẬT: Phiên bản Mongoose (5.5.3)

remove () không được dùng nữa và thay vào đó, bạn có thể sử dụng removeOne (), removeMany () hoặc BulkWrite ().

"mongoose": ">=2.7.1"bạn có thể xóa tài liệu trực tiếp bằng .remove()phương pháp thay vì tìm tài liệu và sau đó xóa tài liệu đó có vẻ hiệu quả và dễ bảo trì hơn.

Xem ví dụ:

Model.remove({ _id: req.body.id }, function(err) {
    if (!err) {
            message.type = 'notification!';
    }
    else {
            message.type = 'error';
    }
});

CẬP NHẬT:

Đối với cầy mangut 3.8.1, có một số phương pháp cho phép bạn xóa trực tiếp một tài liệu, giả sử:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Tham khảo tài liệu API mongoose để biết thêm thông tin.


13
Như đã lưu ý trong các nhận xét khác cho các câu trả lời khác, điều này bỏ qua phần mềm trung gian được xác định trên lược đồ và có thể thực sự nguy hiểm. Vì vậy, chỉ sử dụng nó nếu bạn hiểu tác động sẽ có. Để biết thêm thông tin, hãy xem mongoosejs.com/docs/middleware.html
Jed Watson

2
Chỉ để ghi lại, cho đến bây giờ tôi luôn sử dụng chúng mà không có bất kỳ tác dụng phụ nào, chắc chắn, tôi đã không sử dụng bất kỳ phần mềm trung gian nào trong các dự án của mình :)
diosney

8
remove(query)có khả năng có thể làm trống toàn bộ bộ sưu tập của bạn nếu bạn vô tình vượt qua query = {}. Vì lý do đó tôi thích findOneAndRemove(query)nếu tôi chỉ xóa một tài liệu.
joeytwiddle

1
Cũng lưu ý rằng điều này không trả về một truy vấn, vì vậy cũng không phải là một lời hứa. Bạn không thể làmModel.remove({ _id: 'whatever' }).exec().then(...)
David

48

docslà một mảng các tài liệu. Vì vậy, nó không có một mongooseModel.remove()phương pháp.

Bạn có thể lặp và loại bỏ từng tài liệu trong mảng riêng biệt.

Hoặc - vì có vẻ như bạn đang tìm tài liệu bằng một id duy nhất (có thể) - sử dụng findOnethay vì find.


5
Nhìn thấy câu trả lời này giả định một phiên bản cầy mangut khá cũ, tôi thực sự sẽ không phản đối việc ai đó thay đổi câu trả lời được chấp nhận.
mtkopone

Đây thực sự là một trong những cách tốt nhất để làm điều đó bởi vì nó gọi chính xác phần mềm trung gian được xác định trên lược đồ - xem mongoosejs.com/docs/middleware.html . Bạn chỉ nên sử dụng các phương pháp khác nếu bạn KHÔNG sử dụng phần mềm trung gian trong ứng dụng của mình và sau đó thận trọng.
Jed Watson

41

Điều này đối với tôi là tốt nhất kể từ phiên bản 3.8.1:

MyModel.findOneAndRemove({field: 'newValue'}, function(err){...});

Và nó chỉ yêu cầu một cuộc gọi DB. Sử dụng điều này cho rằng bạn không thực hiện bất kỳ removehành động nào để tìm kiếm và loại bỏ.


1
Miễn là bạn không cần thực hiện pre 'remove'các hành động thì nó hoạt động tốt.
Daniel Kmak

32

Đơn giản chỉ cần làm

FBFriendModel.remove().exec();

1
Đơn giản và hiệu quả.
Apodaca giàu

1
Điều này có trả lại một lời hứa không? Nếu vậy, đối tượng nào được xác định khi Lời hứa được giải quyết?
Kenny Worden

@KennyWorden một cách tiếp cận hiệu quả để tìm câu trả lời -> mongoosejs.com/docs/api.html sau đó tìm kiếm những gì bạn muốn nhưng trả trước '#' cho tìm kiếm trong trang bằng trình duyệt của bạn, chẳng hạn như tìm kiếm trên '#save' và bạn Sẽ thấy nó trả lại một lời hứa.
Jason Sebring

3
Đây là một câu trả lời nguy hiểm mà không đặt điều kiện op được chỉ định trong xóa ...
blak3r

29

mongoose.model.find()trả về một đối tượng truy vấn cũng có remove()chức năng.

Bạn cũng có thể sử dụng mongoose.model.findOne()nếu bạn muốn xóa chỉ một tài liệu duy nhất.

Khác, bạn có thể làm theo cách tiếp cận truyền thống cũng như nơi đầu tiên bạn lấy tài liệu và sau đó xóa.

yourModelObj.findById(id, function (err, doc) {
    if (err) {
        // handle error
    }

    doc.remove(callback); //Removes the document
})

Sau đây là các cách trên modelđối tượng bạn có thể thực hiện bất kỳ thao tác nào sau đây để xóa (các) tài liệu:

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

var query = Comment.remove({ _id: id });
query.exec();

22

remove()đã bị phản đối Sử dụng deleteOne(), deleteMany()hoặcbulkWrite() .

Mã tôi sử dụng

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });

1
Câu trả lời này trung thực cần nhiều upvote. Nó không công bằng được đặt ở đáy thùng (vì nó đã không nhận được nửa thập kỷ cổ phiếu), nhưng là câu trả lời duy nhất giải quyết vấn đề:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia

18

Để khái quát bạn có thể sử dụng:

SomeModel.find( $where, function(err,docs){
  if (err) return console.log(err);
  if (!docs || !Array.isArray(docs) || docs.length === 0) 
    return console.log('no docs found');
  docs.forEach( function (doc) {
    doc.remove();
  });
});

Một cách khác để đạt được điều này là:

SomeModel.collection.remove( function (err) {
  if (err) throw err;
  // collection is now empty but not deleted
});

18

Hãy cẩn thận với findOne và loại bỏ!

  User.findOne({name: 'Alice'}).remove().exec();

Đoạn mã trên loại bỏ TẤT CẢ người dùng có tên 'Alice' thay vì chỉ người đầu tiên .

Nhân tiện, tôi thích xóa các tài liệu như thế này:

  User.remove({...}).exec();

Hoặc cung cấp một cuộc gọi lại và bỏ qua exec ()

  User.remove({...}, callback);


12

Nếu bạn đang tìm kiếm chỉ một đối tượng bị xóa, bạn có thể sử dụng

Person.findOne({_id: req.params.id}, function (error, person){
        console.log("This object will get deleted " + person);
        person.remove();

    });

Trong ví dụ này, Mongoose sẽ xóa dựa trên kết hợp req.params.id.


Chào mừng bạn đến với Stackoverflow. Câu trả lời của bạn là một bản sao của nhiều câu trả lời trong chủ đề này. Ngoài ra, bạn phải luôn luôn kiểm tra lỗi trong các cuộc gọi lại của bạn.
VtoCorleone

9

.remove()hoạt động như .find():

MyModel.remove({search: criteria}, function() {
    // removed.
});

9

Tôi thích ký hiệu lời hứa, nơi bạn cần, vd

Model.findOneAndRemove({_id:id})
    .then( doc => .... )

7

Để xóa tài liệu, tôi thích sử dụng Model.remove(conditions, [callback])

Vui lòng tham khảo tài liệu API để xóa: -

http://mongoosejs.com/docs/api.html#model_Model.remove

Trong trường hợp này, mã sẽ là: -

FBFriendModel.remove({ id : 333 }, function(err, callback){
console.log(‘Do Stuff’);
})

Nếu bạn muốn xóa tài liệu mà không cần chờ phản hồi từ MongoDB, đừng vượt qua cuộc gọi lại, thì bạn cần gọi exec trên Truy vấn được trả về

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();

6

Bạn chỉ có thể sử dụng truy vấn trực tiếp trong hàm remove, vì vậy:

FBFriendModel.remove({ id: 333}, function(err){});

6

Bạn luôn có thể sử dụng chức năng tích hợp Mongoose:

var id = req.params.friendId; //here you pass the id
    FBFriendModel
   .findByIdAndRemove(id)
   .exec()
   .then(function(doc) {
       return doc;
    }).catch(function(error) {
       throw error;
    });

5

Cập nhật: không dùng nữa .remove()nhưng điều này vẫn hoạt động cho các phiên bản cũ hơn

YourSchema.remove({
    foo: req.params.foo
}, function(err, _) {
    if (err) return res.send(err)
    res.json({
        message: `deleted ${ req.params.foo }`
    })
});

Model.remove không được dùng nữa
Maxwell sc

2

sử dụng phương thức remove () bạn có thể xóa.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }

Model.remove không được dùng nữa
Maxwell sc

1
Maxwell sc, thực hiện một yêu cầu chỉnh sửa sau đó, và chính xác. Tôi biết bạn chưa quen với SO, nhưng cách khắc phục nó hữu ích hơn là nhận xét rằng nó không được dùng nữa. Có lẽ bạn có thể đề xuất chỉnh sửa vào lần tới hoặc tự chỉnh sửa và sở hữu một chút về tình huống này ...
Joshua Michael Wagoner

1

Điều này làm việc cho tôi, chỉ cần thử điều này:

const id = req.params.id;
      YourSchema
      .remove({_id: id})
      .exec()
      .then(result => {
        res.status(200).json({
          message: 'deleted',
          request: {
            type: 'POST',
            url: 'http://localhost:3000/yourroutes/'
          }
        })
      })
      .catch(err => {
        res.status(500).json({
          error: err
        })
      });

Model.removekhông được chấp nhận
Maxwell sc

1

Theo câu trả lời của Samyak Jain, tôi sử dụng Async Await

let isDelete = await MODEL_NAME.deleteMany({_id:'YOUR_ID', name:'YOUR_NAME'});

0

Tôi thực sự thích mẫu này trong async / await các ứng dụng Express / Mongoose có khả năng :

app.delete('/:idToDelete', asyncHandler(async (req, res) => {
  const deletedItem = await YourModel
    .findByIdAndDelete(req.params.idToDelete) // This method is the nice method for deleting
    .catch(err => res.status(400).send(err.message))

  res.status(200).send(deletedItem)
}))

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.