如何合并不同集合的游标并按日期排序

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

本文关键字:游标 排序 日期 集合 何合并 合并      更新时间:2023-09-26

是否可以合并两个或多个不同的collections并通过createdAt对其进行排序?

例如,我有一些像这样的数据

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

我想在服务器上合并并订购它们,以便客户端稍后通过订阅获得合并的CollectionC。如何合并和排序集合?我想尽可能便宜地这样做

无法同时查询这两个集合。所以你有两个解决方案:

  • 非常糟糕的一个:用一个查询从collectionA中选择所有内容,用另一个查询选择collectionB中的所有内容,在应用层上对所有内容进行排序,然后得到结果。很容易看出,一旦你有了任何合理的尺寸,这就变得不可缩放了。您可以进行变通(比如只选择靠近createdAt的元素),但这仍然很糟糕
  • 如果集合中的数据如此相似,为什么需要两个集合。重构数据库并将它们合并在一起(如果出于某种原因,您需要知道它们来自哪些集合,请添加字段type: 1|2。这样,您将在数据库层(而不是应用程序层)上进行排序

我该如何将它们合并。我会在mongoshell用做这件事

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

在这之后,你将只得到collectionB,它将拥有来自两个集合的文档。

长话短说:您必须在应用程序端执行此操作,因为游标与集合绑定。因此,您必须手动合并结果集。

合并后,可以使用以下方法对它们进行排序

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)