Dude
Dude

Reputation: 1045

how to merge cursors of different collections and order them by date

is it possible to merge two or more different collections and order them by createdAt?

e.g. I have some data like

    CollectionA.insert({
        createdAt: new Date(),
        field1: value1,
        field2: value3,
        field3: value2,
    });
    CollectionB.insert({
        createdAt: new Date(),
        field4: value4,
        field5: value5,
        field6: value6,
        field7: value7,
    });

I would like to merge and order them on the server that the client get a merged CollectionC later via a subscribe. How to merge and order the collections? I would like to do this as cheap as possible

Upvotes: 0

Views: 2168

Answers (2)

Salvador Dali
Salvador Dali

Reputation: 222491

There is no way to query both collections together. So you have two solutions:

  • pretty bad one: select everything from collectionA with one query, select everything from collectionB with another, sort everything on application layer and get your results. It is easy to see that once you have any reasonable size, this becomes unscalable. You can do work arounds (like select only elements only close to createdAt) but it is still bad.
  • what I would do. If the data in collections is that similar, why do you need both collections. Refactor your db and merge them together (if for some reason you need to know which collections they came from add a field type: 1|2. This way you will sort on a db layer (not application layer.

How would I merge them. I would do this in mongoshell with:

db.collectionA.find().forEach(function(doc){
   db.collectionB.insert(doc);
});
db.collectionA.drop()

After this you will end up only with collectionB which will have the documents from both collections.

Upvotes: 2

Markus W Mahlberg
Markus W Mahlberg

Reputation: 20693

To make a long story short: You have to do this on the application side, as cursors are tied to collections. So you have to manually merge the result sets.

After you merged them, you can use the following approach to sort them

function sortByField(a,b){
  if(a.fieldName < b.fieldName) {
    return -1;
  }
  else if(a.fieldName == b.fieldName){
     return 0;
  }
  else return 1;
}

var sortedArray = mergedArray.sort(sortByField)

Upvotes: 1

Related Questions