Mongo 同时从 2 个集合中获取值

Mongo get value from 2 collections same time

我正在尝试从 2 个集合中获取数据,return 一个包含两个集合的合并数据的数组。

对我来说最好的解决方案是:

const bothValues = await ValueA.aggregate([
      { $unionWith: { coll: 'valueB' } },
      { $sort: { rank: -1, _id: -1 } },
      {
        $match: {
          isAvailable: true,
        },
      },
      { $skip: skip },
      { $limit: 30 },
    ]);

效果很好。但是.. $unionWith 没有实现我的 MongoDB 版本 (4.0.X) 所以我不能使用它。

const bothValues = await ValueA.aggregate(
      [
        { $limit: 1 },
        {
          $lookup: {
            from: 'valueB',
            pipeline: [{ $limit: 15 }],
            as: 'valueB',
          },
        },
        {
          $lookup: {
            from: 'ValueA',
            pipeline: [{ $limit: 15 }, { $sort: { rank: -1, _id: -1 } }],
            as: 'ValueA',
          },
        },
        {
          $project:
          {
            Union: { $concatArrays: ['$valueB', '$ValueA'] },
          },
        },
        { $unwind: '$Union' },
        { $replaceRoot: { newRoot: '$Union' } },
      ],
    );

但是现在,我遇到了 2 个问题:

谢谢

查询

  • 您的查询经过一些更改后可以像第一个查询一样工作
  • 在两个管道中匹配,在两个管道中排序,(limit limitN+skipN) (这样我们确保我们总是有足够的文档,即使所有的文档都取自 valueA 或 valueB)
  • 从每个中取出排序的 70 个,所以在所有方面我们将在并集后的最终 sort/skip/limit 中得到所需的 70 个。
  • concat,unwind,replace-root 就像在你的查询中一样
  • 再次排序(现在对并集排序),跳过,限制
  • 无论我们总是有足够的文件可以跳过
  • 此示例查询针对 skip=40limit=30,因此在前 2 个管道中我们 limit=70
db.ValueA.aggregate([
  {
    "$limit": 1
  },
  {
    "$lookup": {
      "from": "valueB",
      "pipeline": [
        {
          "$match": {
            "isAvailable": true
          }
        },
        {
          "$sort": {
            "rank": -1,
            "_id": -1
          }
        },
        {
          "$limit": 70
        }
      ],
      "as": "valueB"
    }
  },
  {
    "$lookup": {
      "from": "valueA",
      "pipeline": [
        {
          "$match": {
            "isAvailable": true
          }
        },
        {
          "$sort": {
            "rank": -1,
            "_id": -1
          }
        },
        {
          "$limit": 70
        }
      ],
      "as": "valueA"
    }
  },
  {
    "$project": {
      "union": {
        "$concatArrays": [
          "$valueA",
          "$valueB"
        ]
      }
    }
  },
  {
    "$unwind": {
      "path": "$union"
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$union"
    }
  },
  {
    "$sort": {
      "rank": -1,
      "_id": -1
    }
  },
  {
    "$skip": 40
  },
  {
    "$limit": 30
  }
])