Let's say I have a Person collection, and a Car collection, and that all people have a single car, and the Person document stores the Id of the car.
Somewhere along the way, due to bad back-end validation, some Cars have been persisted to the DB, without any owners. I would like to delete all these 'orphan' cars.
My approach is probably not the most optimal, but here goes:
exports.cleanOrphanCars = (req, res) ->
Car.find() #find all the cars
.exec(err, cars) ->
return res.send(StatusMessages.ERROR.code, { error: err }) if err?
carIds = cars.map (car) =>
#map the IDs to a new array for faster iteration
return car._id
Person.find()
.exec(err, people) ->
peoplesCarIds = (person) =>
return person.carId
for carId in carIds
found = false
for personsCarId in peoplesCarIds
if personCarId is carId
found = true
if not found
#if no Person references this car, we can remove it
Car.remove({_id : carId})
Getting all these Cars and Persons is too slow. Is there a way to fetch an array of IDs straight from mongo, without me having to map the IDs locally?
Also would it be possible to skip the prefetching and have just one query to remove any orphan Cars?
Use Person.distinct to get an array of _id values of all people's cars and then use $nin with Car.remove to remove the cars with an _id that's not in that set:
Person.distinct('carId', function (err, ids) {
Car.remove({_id: {$nin: ids}}, function (err) { ... });
});