Jak usunąć dokumenty za pomocą Node.js Mongoose?


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

Powyższe wydaje się nie działać. Dokumenty wciąż tam są.

Czy ktoś może to naprawić?

Odpowiedzi:


489

Jeśli nie masz ochoty na iterację, spróbuj FBFriendModel.find({ id:333 }).remove( callback );lubFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.findzwraca zapytanie , które ma removefunkcję .

Aktualizacja Mongoose v5.5.3 - remove()jest już nieaktualna. Stosowanie deleteOne(), deleteMany()lubfindOneAndDelete() instead.


3
Czy to działa przed / po usunięciu oprogramowania pośredniego? (niektóre metody modelowe omijają oprogramowanie pośrednie dokumentów i nie jestem pewien, czy jest to jedna z nich, dokumenty są niejasne)
hunterloftis

12
Podejrzewam, że @hunterloftis już to zrozumiał, ale dla każdego, kto przeczyta odpowiedź, nie, nie będzie ono uruchamiać oprogramowania pośredniego przed / po na poszczególnych dokumentach.
numery1311407

Wydaje się, że wiele innych odpowiedzi wspomina, .exec()jednak wcale tak nie jest. Czy jest .exec()potrzebny, czy są jakieś skutki uboczne korzystania z niego, czy nie?
DanH

Dokumenty są jasne (być może zostały zaktualizowane), że omija to oprogramowanie pośrednie - patrz na dole mongoosejs.com/docs/middleware.html - więc bądź ostrożny, użycie tej metody może spowodować poważne, trudne do wyśledzenia problemy.
Jed Watson

1
świetna odpowiedź! jakie są argumenty wywołania zwrotnego?
k88074,

299

AKTUALIZACJA: Wersja Mongoose (5.5.3)

remove () jest przestarzałe i można zamiast niego użyć deleteOne (), deleteMany () lub bulkWrite ().

W "mongoose": ">=2.7.1"tym momencie możesz usunąć dokument bezpośrednio za pomocą .remove()metody, zamiast znajdować go, a następnie usuwać, co wydaje mi się bardziej wydajne i łatwe w utrzymaniu.

Zobacz przykład:

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

AKTUALIZACJA:

W przypadku mangusty 3.8.1istnieje kilka metod, które pozwalają bezpośrednio usunąć dokument, na przykład:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Więcej informacji można znaleźć w dokumentacji interfejsu API mangusty .


13
Jak zauważono w innych komentarzach do innych odpowiedzi, omija to oprogramowanie pośrednie zdefiniowane w schemacie i może być naprawdę niebezpieczne. Dlatego używaj go tylko wtedy, gdy rozumiesz wpływ, który będzie miał. Aby uzyskać więcej informacji, zobacz mongoosejs.com/docs/middleware.html
Jed Watson

2
Dla przypomnienia, do tej pory zawsze używałem ich bez żadnych skutków ubocznych, na pewno nie musiałem używać oprogramowania pośredniego w swoich projektach :)
diosney

8
remove(query)może potencjalnie opróżnić całą kolekcję, jeśli przypadkowo przejdziesz query = {}. Z tego powodu wolę, findOneAndRemove(query)jeśli usuwam tylko jeden dokument.
joeytwiddle

1
Zauważ też, że to nie zwraca zapytania, więc ani obietnicy. Nie możesz tego zrobićModel.remove({ _id: 'whatever' }).exec().then(...)
David,

48

docsto tablica dokumentów. więc nie ma mongooseModel.remove()metody.

Możesz iterować i usuwać każdy dokument z tablicy osobno.

Lub - ponieważ wygląda na to, że znajdujesz dokumenty według (prawdopodobnie) unikalnego identyfikatora - użyj findOnezamiast find.


5
Widząc, że ta odpowiedź zakłada raczej starą wersję mangusty, naprawdę nie sprzeciwiłbym się zmianie przez kogoś zaakceptowanej odpowiedzi.
mtkopone

Jest to w rzeczywistości jeden z najlepszych sposobów, aby to zrobić, ponieważ poprawnie wywołuje oprogramowanie pośrednie zdefiniowane w schemacie - patrz mongoosejs.com/docs/middleware.html . Powinieneś używać innych metod tylko wtedy, gdy NIE używasz oprogramowania pośredniego w swojej aplikacji, a następnie zachowaj ostrożność.
Jed Watson

41

To jest dla mnie najlepsze od wersji 3.8.1:

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

I wymaga tylko jednego wywołania DB. Użyj tego, biorąc pod uwagę, że nie wykonujesz żadnych removeczynności do wyszukiwania i usuwania.


1
Tak długo, jak nie musisz wykonywać pre 'remove'czynności, działa dobrze.
Daniel Kmak

32

Po prostu zrób

FBFriendModel.remove().exec();

1
Prosty i skuteczny.
Rich Apodaca

1
Czy to zwraca obietnicę? Jeśli tak, to jaki obiekt jest definiowany po rozstrzygnięciu Obietnicy?
Kenny Worden,

@KennyWorden skuteczne podejście do znalezienia odpowiedzi -> mongoosejs.com/docs/api.html, a następnie wyszukaj to, co chcesz, ale wstaw „'” do wyszukiwania na stronie za pomocą przeglądarki, np. „#Save”, a ty Zobaczę, czy zwróci obietnicę.
Jason Sebring

3
Jest to rodzaj niebezpiecznej odpowiedzi bez stawiania warunku operacji określonego w remove ...
blak3r

29

mongoose.model.find()zwraca obiekt zapytania, który również ma remove()funkcję.

Możesz również użyć mongoose.model.findOne(), jeśli chcesz usunąć tylko jeden unikalny dokument.

W przeciwnym razie możesz postępować zgodnie z tradycyjnym podejściem, w którym najpierw pobierasz dokument, a następnie go usuwasz.

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

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

Poniżej przedstawiono sposoby modelobiektu, które możesz wykonać, aby usunąć dokument (y):

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

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

22

remove()został wycofany. Użyj deleteOne(), deleteMany()lub bulkWrite().

Kod, którego używam

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

1
Ta odpowiedź szczerze potrzebuje więcej głosów pozytywnych. Jest niesprawiedliwie umieszczony na dnie beczki (ponieważ nie otrzymał pół dekady przestarzałych głosów), ale jest jedyną odpowiedzią, która rozwiązuje problem:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia

18

Aby uogólnić, możesz użyć:

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();
  });
});

Innym sposobem na osiągnięcie tego jest:

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

18

Bądź ostrożny z findOne i usuń!

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

Powyższy kod usuwa WSZYSTKICH użytkowników o nazwie „Alice” zamiast tylko pierwszego .

Nawiasem mówiąc, wolę usunąć takie dokumenty:

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

Lub podaj wywołanie zwrotne i pomiń exec ()

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


12

Jeśli szukasz tylko jednego obiektu do usunięcia, możesz użyć

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

    });

W tym przykładzie Mongoose usunie na podstawie pasującego pliku req.params.id.


Witamy w Stackoverflow. Twoja odpowiedź jest duplikatem wielu odpowiedzi w tym wątku. Ponadto zawsze należy sprawdzać, czy nie występują błędy w wywołaniach zwrotnych.
VtoCorleone

9

.remove()działa jak .find():

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

9

Wolę notację obietnicy, w której potrzebujesz np

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

7

Do usuwania dokumentu wolę używać Model.remove(conditions, [callback])

Odwołaj się do dokumentacji API, aby usunąć: -

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

W tym przypadku kod będzie:

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

Jeśli chcesz usunąć dokumenty bez oczekiwania na odpowiedź z MongoDB, nie przekazuj połączenia zwrotnego, musisz wywołać exec na zwróconym zapytaniu

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

6

Możesz po prostu użyć zapytania bezpośrednio w funkcji usuwania, więc:

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

6

Zawsze możesz użyć wbudowanej funkcji 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

Aktualizacja: .remove()jest nieaktualna, ale nadal działa dla starszych wersji

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

Model.remove jest przestarzały
Maxwell sc

2

za pomocą metody remove (), którą możesz usunąć.

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

Model.remove jest przestarzały
Maxwell sc

1
Maxwell sc, złóż wniosek o edycję i popraw. Wiem, że jesteś nowy w SO, ale o wiele bardziej pomocne jest naprawienie go niż skomentowanie jego amortyzacji. Może mógłbyś zasugerować edycję następnym razem lub sam dokonać edycji i wziąć trochę odpowiedzialności za sytuację ...
Joshua Michael Wagoner

1

To działało dla mnie, po prostu spróbuj tego:

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.removejest przestarzałe
Maxwell sc

1

Zgodnie z odpowiedzią Samyaka Jaina używam Async Await

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

0

Bardzo podoba mi się ten wzorzec w aplikacjach obsługujących funkcje asynchroniczne / oczekujące na ekspres / Mongoose:

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)
}))

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.