What is the most effective way to make mongo “leftJoin” in Meteor? Which way do you prefer?
a) aggregate
By my experience is, it’s slow
Meteor.publish('ordersWithUsers', function () {
return Orders.rawCollection().aggregate([
{
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'userInfo'
}
},
{
$unwind: {
path: '$userInfo',
preserveNullAndEmptyArrays: true
}
}
]).toArray();
});
b) manually selected
Memory uneffective and risky, if there is a lot of users.
const orders = Orders.find().fetch();
const userIds = [...new Set(orders.map(o => o.userId))];
const users = Users.find({ _id: { $in: userIds } }).fetch();
const enrichedOrders = orders.map(order => {
const user = users.find(u => u._id === order.userId);
return {
...order,
user: user || null,
};
});
c) denormalization
Risky for “unactual” data, fastest, but redundant data:
Orders.insert({
product: 'Coffee',
userId: 'abc123', // ID to identify user
user: { // User object data
userName: 'John Smith'
}
});
d) denormalization 2
Risky for “unactual” data, fastest, but redundant data,
on the other side, I like, when I do not have userId and then also user object BUT:
disadvantage is, if I need to filter by userId, I must filter by user._id
Orders.insert({
product: 'Coffee',
user: { // Same as previous, but without userId field (_id is used instead)
_id: 'abc123'
userName: 'John Smith'
}
});
e) something else?
Very important part of this question is also, if I would like to make a selection by leftJoin of leftJoined collection, for example: “book”->“book_categories”->“book_category_types” (get all books from collection “books” where “book_category_types” creationDate is in current year). What to do in this case? Denormalization? Aggregate through multiple collection (slow)? What is also important to tell is, that all selected data I’m using in datagrid, therefore in selection process, I need to use pagination, filtering and sorting.
Thanks a lot for and each recommendation or experience.