Return 2D Mongo Array

I have some data stored in my DB like so:

groups: {
 group1: ['userId1', 'userId2'],
 group2: ['userId3', 'userId4'],
 group3: ['userId5', 'userId6'],
}

I would like to get those users from the Meteor.users.fetch() Is it possible to get the data like so with one query?

[
  group1: [{user1Obj}, {user2Obj}],
  group1: [{user3Obj}, {user4Obj}],
]

Thanks

whats meaning “user10bj” ?

userObj1, userObj2 ... is basically the Meteor.users.find() object

{
  _id: '123456'
  profile: { ... profile data }
}
1 Like

ok, I’m confusing ‘user1Obj’ with ‘user10bj’ (with zero…)
:smiley:

So these are an array of userId's that I have grouped in the DB:

groups: {
 group1: ['userId1', 'userId2'], //array of user ID's
 group2: ['userId3', 'userId4'],
 group3: ['userId5', 'userId6'],
}

So when I execute my query, I will get the entire user object instead of the ID’s I have stored.

I know I can use a query like so to get all the user objects:

Meteor.users.find({$in: [...group1, ...group2, ...group3 ]})

But I wanted to know if I can get the data returned in a structured manner like so:

[
  group1: [{_id: userId1, profile: {}}, {_id: userId2, profile: {}}],
  group2: [{_id: userId3, profile: {}}, {_id: userId4, profile: {}}],
  group3: [{_id: userId5, profile: {}}, {_id: userId6, profile: {}}],
]

I want to return one array with the user objects in their respective groups.

Hopefully that makes more sense.

Thanks.

Getting your data structured the way you want seems like a question of whether to use one query with joins vs multiple queries that get you the desired result. This may help regarding the first scenario: $lookup (aggregation) — MongoDB Manual

Regarding multiple queries, another approach would be to get your groups data like so: perform first query to get

var groups = {
 group1: ['userId1', 'userId2'], //array of user ID's
 group2: ['userId3', 'userId4'],
 group3: ['userId5', 'userId6'],
}

Then

Object.keys(groups).forEach(function(groupItemArray){
    groupItemArray.forEach(theUserId, itemIndex){
        groupItemArray[itemIndex] = Meteor.users.findOne(theUserId); 
    });
});

To be sure, this isn’t valid JS (since arrays don’t have string-keyed properties like, for example, PHP does):

[
  group1: [{_id: userId1, profile: {}}, {_id: userId2, profile: {}}],
  group2: [{_id: userId3, profile: {}}, {_id: userId4, profile: {}}],
  group3: [{_id: userId5, profile: {}}, {_id: userId6, profile: {}}],
]

I think you meant for an array objects like:

[
  {group1: [{_id: userId1, profile: {}}, {_id: userId2, profile: {}}]},
  {group2: [{_id: userId3, profile: {}}, {_id: userId4, profile: {}}]},
  {group3: [{_id: userId5, profile: {}}, {_id: userId6, profile: {}}]},
]

If your Meteor.users record also has information of groups it belongs to

eg. some field in userid1 record
xxxx: [‘group1’,‘group3’]

then it is possible to do it using aggregates in one query…using unwind and grouping…I think

Thanks for the responses and suggestions, I think for efficiency and simplicity I will need to store the group data on the User object instead of a Group object as I currently have it.

Thanks again!

Happy to help. For what it’s worth, I’m using a very similar db collection scheme where I have users and separately groups (I call them spaces but it’s a similar concept as far as I can tell). I like the separation of concerns with the collections, as each can hold data that’s relevant for that collection, but still have the server-side flexibility to combine the data into an idealized structure I can ship to the browser.

Great minds think alike? :slight_smile:

Have you observed any performance penalties for such a design and query structure?

Not at all. Part of that may be due to Meteor’s magic and well-built framework, but I’m also careful with expensive queries and non-indexed databases (which is important regardless of the database engine you’re employing). So the existing queries are fast, and once you have the data from the queries, looping/combining things on the server is quick.

Of course, it depends on your collections’ structure, how much data you’re querying/combining, but overall everything is quick and snappy with my approach.