2

I have this collection, the objects in them look like:

{
  name: 'Apple',
  listOrder: {
    default: 1,
    wallmart: 1
  }
  color: 'Red'
},
{
  name: 'Orange',
  listOrder: {
    default: 2,
    wallmart: 3
  }
  color: 'Orange'
},
{
  name: 'Lemon',
  listOrder: {
    default: 3,
    wallmart: 2
  }
  color: 'Yellow'
}

I have 3 fruit stands that need to get them back in the right order. I have tried several different ways to do this, and I feel that I'm on the right track with:

function getFruit(storeName){
  var override = {check:{}, sort:{}}
  override.check[`listOrder.${store}`] = {$exists:1}
  override.sort[`order.${store}`] = 1

  var sort = {sort:{$cond:{if:override.check, then:override.sort, else:{'listOrder.default':1}}}}

  return FruitsCollection.find({}, sort).fetch()
}

It tells me that $cond is not a supported sort key. I am wondering 3 things:

  1. Would it be better optimized to sort them on the client? I'm trying to keep mobile in mind, so, sorting like this makes the page take several seconds to load as I have faaar more than just these 3 fruits.
  2. Is there a better sort query that I can use? I'm a bit new to Mongo.
  3. Is this just a generally bad idea?

This is currently being used on the client, I can move it to the server, however it also tells me I'm using a bad sort specification.

Spencer Cornwall
  • 289
  • 2
  • 14

1 Answers1

1

The $cond operator is used in an aggregation, which is not a simple query using .find.

Meteor itself uses the MongoDB driver for NodeJS but not directly (it abstracts the Mongo calls into the Meteor environment for you), so you are not able to just call collection.aggregate.

However, you can either use the native collection via rawCollection and then handle all the async operations manually (for more experienced users) or use one of the several packages for proper aggregation out there, for example:

Single aggregations: https://github.com/sakulstra/meteor-aggregate/

Publications with aggreagtions: https://github.com/robfallows/tunguska-reactive-aggregate/

Jankapunkt
  • 8,128
  • 4
  • 30
  • 59
  • I'll take a look into those, I wish I had a bit more experience with mongo, but, I guess that'll come with time – Spencer Cornwall Nov 14 '19 at 01:53
  • The aggregation in publications seemed promising, but they only allow for $meta operator in their $sort pipline. The single aggregations has the same issue as the regular meteorhacks packages, and I can't seem to find where the raw collection would be of use. – Spencer Cornwall Nov 14 '19 at 16:08
  • The raw collection is the native mongo collection on which you can also make `aggregate` calls but you will have to manage the returned data to be pubslished etc. on your own. The tunguska package is maintained and the owner is usually very active in the Meteor community. Maybe you leave him an issue and discuss your requirements regarding the sort operation. – Jankapunkt Nov 14 '19 at 16:24
  • I actually solved it by simply using a 2 layer sort, sorting first by the default, and then by the store, that way, if there is no store, it's still sorted. – Spencer Cornwall Nov 15 '19 at 17:26