0

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

Dude
  • 1,045
  • 2
  • 15
  • 36
  • can you please clarify your question. You told that you need to merge `different` collections, but in your example you have only collectionA. Also what would you like to order in these collections? – Salvador Dali Apr 08 '15 at 21:47
  • Fixed typo and updated question – Dude Apr 08 '15 at 21:49
  • possible duplicate of [MongoDB: Combine data from multiple collections into one..how?](http://stackoverflow.com/questions/5681851/mongodb-combine-data-from-multiple-collections-into-one-how) – Pio Apr 08 '15 at 22:28
  • 1
    Take a look at [this](http://stackoverflow.com/questions/5681851/mongodb-combine-data-from-multiple-collections-into-one-how) and [this](http://stackoverflow.com/questions/9696940/merging-two-collections-in-mongodb). Then you can index it by date and that's it. – Pio Apr 08 '15 at 22:30

2 Answers2

2

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.

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
1

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)
Markus W Mahlberg
  • 19,711
  • 6
  • 65
  • 89