user3142695 user3142695 - 4 months ago 22
Javascript Question

JS/MongoDB: How to remove all nested documents by given parent title

In my mongoDB there are some main documents and some children:

{ _id: 'KZg2RgcnxdfYbAoog',
title: 'Article Sample',
type: 'articles' }

{ _id: 'YbAoogKZg2Rgcnxdf',
parent: 'KZg2RgcnxdfYbAoog' }


Now I need to remove the complete dataset using the title of the main document.

So my approach is to first get all documents matching given title array. With those IDs I tried to remove all documents with this
id
or
parent
.
But with this code I do not get any remove.
articles
seems to be undefined...

Also the complete code looks very huge for that simple task. Can this be done a bit smarter?

MongoClient.connect(mongoUrl, function (err, db) {
expect(err).to.be.null
console.log('Connected successfully to server: ' + mongoUrl)

var articles = db.collection('articles')
var titleArray = ['Article Sample', 'Another sample']

articles.find({ title: { $in: titleArray } }).toArray((err, docs) => {
if (err) console.warn(err)
if (docs && docs.length > 0) {
docs.forEach(doc => {
articles.remove(
{
$or: [
{ _id: doc._id },
{ parent: doc._id },
{ main: doc._id }
]
},
(err, numberOfRemovedDocs) => {
console.log(numberOfRemovedDocs)
}
)
})
}
})

db.close()
})

Answer Source

You're closing the db connection before finding anything. articles.find is async, and you do db.close() right after it.

It should be something like this:

  articles.find({ title: { $in: titleArray } }).toArray((err, docs) => {
    if (err) console.warn(err)
    if (docs && docs.length > 0) {
      Promise.all(
        docs.map(doc => 
          articles.remove(
            {
              $or: [
                { _id: doc._id },
                { parent: doc._id },
                { main: doc._id }
              ]
            }
          )
        )
      )
      .then((res)=>{
        res.map((res)=>{console.log(res.result.n)}); //numberOfRemovedDocs per title
        db.close()
      })
      .catch(()=>{db.close()})
    } else {
      db.close()
    }
  })