Yanick Rochon
Yanick Rochon

Reputation: 53516

Deleting documents that are not indexed in another collection in Meteor

First, I have read a few answers (such as this one), but I'm not sure how I can implement this in Meteor.

I have a collection of items, and another of categories. Categories are created dynamically when the items are saved. Once the document is saved, I want to cleanup all categories that no longer are associated with an item. How do I do that? I'm used to SQL, and I haven't worked much with document-based DBs other than indexers like Lucene.

For example, given two items like

{ _id: "RK9kQSD7frgreYDvg", name: "Item 1", catId: "c4mE7hANtbWxHFAdm" }
{ _id: "569aogaGBYBMonkgg", name: "Item 2", catId: "c4mE7hANtbWxHFAdm" }

and two categories like

{ _id: "mu2KzDbNdTcrZYGKs", name: "Cat A" }
{ _id: "c4mE7hANtbWxHFAdm", name: "Cat B" }

I want to remove "Cat A" since it is no longer referenced by any items.

I guess something like

const Items = new Meteor.Collection('items');
const Categories = new Meteor.Collection('categories');

...

Categories.remove({ _id: { $not: { $in: ... } }); 

but I'm not sure from that point.

Upvotes: 1

Views: 34

Answers (1)

chridam
chridam

Reputation: 103355

Certainly in the right direction though you may need to use the $nin operator in your remove query.

The first query returns all the distinct values of the catId from the items collection in a list. You can just use underscore.js uniq() method, which comes with Meteor and the map() cursor method to create the distinct array. The second operation will then use that list to delete entries in the categories collection.

The following example demonstrates the above:

const Items = new Meteor.Collection('items');
const Categories = new Meteor.Collection('categories');
const catIds = _.uniq(Items.find‌​({}).map((item) => item.catId;)); 

Categories.remove({ "_id": { "$nin": catIds } }); 

Upvotes: 1

Related Questions