Meteor Many-to-Many Relationships & Queries


How can I represent a many-to-many relationship and reactively query that?

I have a collection, ‘Items’, which can have many ‘OptionGroups’. The ‘OptionGroup’ can also belong to many different Items. The Items schema will probably use an array of OptionGroup ID’s. I do not think I will need to store the Items ID’s in the OptionGroup documents as I will not need to get Items for each option group, only get the OptionGroups assigned to each Item.

I read this article which suggested using aggregate, but it says aggregate is not reactive. It suggests making one call to the database for the first collection and another call for the second collection.

I could probably do a nested withQuery call for each Item’s OptionGroups but that seems inefficient - I would rather make 1 initial database call.

I’m using Meteor with Grapher React. Some code is below.

Item collection links:

  parent: {
    type: 'one',
    field: 'parentId',
    collection: MenuCollection || SectionCollection
  options: {
    type: 'many',
    field: 'optionGroups',
    collection: OptionGroupsCollection

Option Groups links:

  item: {
    collection: ItemCollection,
    inversedBy: 'options'

Grapher Query:

createQuery('menusByVenue', {
  menus: {
    $filter({filters, params}) {
      filters.venueId = params.venueId,
      filters.userId = Meteor.userId
    name: 1,
    items: { name: 1 },
    // TODO: This seems like a very hacky way to handle nested sections but 
    //        it's better than a lot of database calls 
    sections: { 
      name: 1, 
      items: { 
        name: 1,
        options: {
          name: 1


Are my links the correct way round? Should I be using a M:M resolving table like in SQL? My createQuery must be wrong as well as I am trying to get options: {} the same way as items and sections but the relationship is different. Sections and Items have parentId’s so are connected to their parent menu or section. Whereas, items is the one with a foreign key, and an array of them at that.

Any advice would be greatly appreciated.

In BowFolios, I accomplish this with separate “join” tables. The readme has a section explaining this:

I also have a screencast about the data model:

I don’t know if this is the correct approach for you, but it’s one way to do it.

1 Like

Thank you, @philipmjohnson!

I thought I might need to use a join table like this but I was wondering if there was an alternative. I will take this approach.