Join data in publications

I know that mongo and meteor is not for joins but how would you do the following? Classical schema with two collections.

Customers

  • active - true/false: customers can be inactive

Orders

  • customerId
  • sum

I need to publish N active customers ordered by sum. I don’t even need cumulative SUM. In SQL I would do it something like this:

select top(N) from customers
left join orders on customers._id = orders.customerId
where customers.active = true
order by sum

Is there a better way rather than do it in two queries? Please also look at some questions in comments:

Meteor.publish("topCustomers", function() {
	// Here I expect array of order IDs ordered by sum: [1, 2, 3, 4]
	let topCustomers = Orders.find({
	
	}, {
		//limit: 10 - I cannot use limit here because some customers might be inactive. Any ideas how to solve it? I don't want to pull ALL orders
		sort: {
			sum: -1
		}
	}).fetch().map(o => o.customerId);
	
	// Here I have to query customers that 
	//   are in topCustomers array
	//   and active
	// I also want them to be in the same order as in topCustomers array. Is there a way to do it?
	return Customers.find({
	
	}, {
           limit: 10 // I need 10 customers only
    });
});
1 Like

I would like to know this too.

BTW is it worth using graphql and apollo for relationships?

Looks like there are 2 questions:

  1. Is there a way to solve this task in a single query? In other words is there a way to filter out one collection basing on other?
  2. Is there a way to sort collection according to a sequence? I mean that I have an array of customer IDs [22, 33, 44, 55] and I want to apply filter like { _id: { $in: [55, 22, 44, 33] } } but also make sure that customers in the second query will be in the same order: [55, 22, 44, 33]. Sorry I mon mongo expert.

Publishing Relational Data

Thank you but it doesn’t answer to any of my questions. I know about publishComposite but it could work only if I would not need to filter out non active customers in the second query and not needed to apply paging limit at the same time.

The second question is more about mongodb. I’m not sure how to sort data according to a sequence.

Sorry - I misunderstood your question.

You could look at two different approaches (assuming you are using MongoDB and not Apollo/GraphQL):

  1. Take a look at grapher, which offers a fresh way of tackling MongoDB queries, or …
  2. If you prefer a more standard approach, look at the MongoDB Aggregation Pipeline, which is a super-performant way of doing complex operations in MongoDB: it also supports joins (an equivalent of left outer join). If you want that with reactive pub/sub in Meteor, look at the jcbernack:reactive-aggregate package.
2 Likes