Meteor Mongo query for subset of array in collection

Hello guys!

I’ve run into a problem when querying for some stuff.

I have a collection called Guestlists containing guestlists. Each element contains a date and some other stuff together with an array called “list”. The “list” array contains elements of each guestlist entry. Every guestlist entry has an “entryOwner” meaning the person who added the entry to the list.

Here is the schema:

Schemas.Guestlist = new SimpleSchema({
  _id: { type: String, regEx: SimpleSchema.RegEx.Id },
  date: { type: Number },
  promoters: { type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: [] },
  list: { type: Array, defaultValue: [] },
  'list.$': { type: Object },
  'list.$.name': { type: String },
  'list.$.entryOwner': { type: String },
  'list.$.comment': { type: String, optional: true },
  'list.$.accepted': { type: Boolean, defaultValue: false },
  'list.$.rejected': { type: Boolean, defaultValue: false },
})

Now comes the problem. I want to query the database and get 1 guestlist and only the guestlist entries for a specific user-ID.

This is what I tried:

Guestlists.find({_id : guestlistID, list: {$elemMatch: {entryOwner: user._id}}}, {fields: { 'list.$': 1}})

However, that only returns the guestlist with one item in the ‘list’ array, which is the first one. How can I get ALL the items in ‘list’ that has the entryOwner I query for?

Also tried this, but gives same result:

Guestlists.find({_id: guestlistID}, {fields: {list: {$elemMatch: {entryOwner: user._id}}}})

It is also important ta keep it as a cursor since I want to return this in my publications

$elemMatch will only return the first matching element from the array. If you want to keep your schema as it is, then you’ll want to use Mongo aggregation. There are several ways to do this with Meteor collections, but here’s a really easy one: meteorhacks:aggregate.

1 Like

I’ll try that out! Thanks!

That worked well. However, I want to subscribe to this data, but a publication must return a cursor. Any idea how I can solve that in a smart fashion?

You can look into wiring up your own cursor.observeChanges based solution, or use a package that already does this for you, like this one: jcbernack:reactive-aggregate.

You just saved me so much trouble! That package worked really good! Thanks.

Good description of how to use it as well!