MongoDB:$union具有单个值

问题描述 投票:0回答:1

我有两个收藏。我需要获取集合 A 中某个字段的最高值,并查找集合 B 中与其字段之一的该值不匹配的所有文档。我怀疑

$unionWith
是我的答案,但我无法让它工作。

这是我的收藏:

BulkTests:

{
   _id: 65b82f4b13f7b6653662795d,
   testDateTime: 2024-01-29T23:05:47.940+00:00,
   testId: 19
},
{
   _id:65bac13912032ee4eae1d47f,
   testDateTime:2024-01-31T21:52:57.185+00:00,
   testId:20
}

-------
Testers:

{
    _id: 65bc139856f9734f1d19285d,
    name: "FooBar Bizzle",
    testResponses:[
        7,
        19
    ]
},
{
    _id: 65bc139856f9734f1d19285d,
    name: "Baz Bar",
    testResponses:[
        20
    ]
}

这是我的聚合管道:

{
    $project: {
      lastTest: {
        $arrayElemAt: [
          "$testResponses",
          {
            $indexOfArray: [
              "$testResponses",
              {
                $max: "$testResponses",
              },
            ],
          },
        ],
      },
      name: 1,
    },
  },
  {
    $match: {
      lastTest: {
        $ne: 20, // this value should be the highest 'testId' from the first collection!
      },
    },
  }

第一阶段为我提供了“测试者”集合中所需的内容:

{
   _id: 65bc139856f9734f1d19285d,
   name: "FooBar Bizzle" ,
   lastTest: 19 
}, 
{
   _id: 65bc139856f9734f1d19285d,
   name: "Baz Bar",
   lastTest: 20 
}

我需要做的是将最终匹配阶段中的“20”替换为第一个集合中“testId”的最大值。我正在战斗

$unionWith
,但它不会达到我想要的效果。我尝试了很多事情......但这里有一个例子:

{   
   coll: 'BulkTests',  
   pipeline: [    
      { $project: { foo: { $max: "$testId"}}},
      {$match:{'foo':'lastTest'}}  
    ] 
}
mongodb aggregation-framework
1个回答
0
投票

对于这种情况,我认为

$facet
阶段应该可以满足您的要求。

  1. $facet
    - 允许在阶段内执行多个管道。

    1.1。

    $lookup
    - 从 BulkTests 集合中获取所有文档。

    1.1.1。

    $unwind
    - 将
    BulkTests
    数组解构为多个文档。

    1.1.1.1。

    $group
    - 将所有文档分组并获取
    testId
    的最大值。

    1.2。

    $project
    - 将 Testers 集合中的输出文档装饰到
    Testers
    数组中。

  2. $unwind
    - 将
    Testers
    数组解构为多个文档。

  3. $match
    - 使用
    Testers.testId
    过滤文档不等于
    maxValue
    数组中
    BulkTests
    的第一个值。

  4. $replaceWith
    - 将输入文档替换为
    Testers
    文档。

db.Testers.aggregate([
  {
    $facet: {
      BulkTests: [
        {
          $lookup: {
            from: "BulkTests",
            let: {},
            pipeline: [],
            as: "BulkTests"
          }
        },
        {
          $unwind: "$BulkTests"
        },
        {
          $group: {
            _id: null,
            maxValue: {
              $max: "$BulkTests.testId"
            }
          }
        }
      ],
      Testers: [
        {
          $project: {
            lastTest: {
              $arrayElemAt: [
                "$testResponses",
                {
                  $indexOfArray: [
                    "$testResponses",
                    {
                      $max: "$testResponses"
                    }
                  ]
                }
              ]
            },
            name: 1
          }
        }
      ]
    }
  },
  {
    $unwind: "$Testers"
  },
  {
    $match: {
      $expr: {
        $ne: [
          "$Testers.lastTest",
          {
            $arrayElemAt: [
              "$BulkTests.maxValue",
              0
            ]
          }
        ]
      }
    }
  },
  {
    $replaceWith: "$Testers"
  }
])

演示@Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.