我有两个收藏。我需要获取集合 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'}}
]
}
对于这种情况,我认为
$facet
阶段应该可以满足您的要求。
$facet
- 允许在阶段内执行多个管道。
1.1。
$lookup
- 从 BulkTests 集合中获取所有文档。
1.1.1。
$unwind
- 将 BulkTests
数组解构为多个文档。
1.1.1.1。
$group
- 将所有文档分组并获取testId
的最大值。
1.2。
$project
- 将 Testers 集合中的输出文档装饰到 Testers
数组中。
$unwind
- 将 Testers
数组解构为多个文档。
$match
- 使用 Testers.testId
过滤文档不等于 maxValue
数组中 BulkTests
的第一个值。
$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"
}
])