如何在一个有序的MongoDB集合中获得所有的前N个类型?



假设我有一个看起来像这样的集合:

[{
_id: new ObjectId(),
type: 'foo',
value: 123,
date: '2022-06-30',
}, {
_id: new ObjectId(),
type: 'bar',
value: 321,
date: '2022-06-29',
}, {
_id: new ObjectId(),
type: 'foo',
value: 456,
date: '2022-06-28',
}, {
_id: new ObjectId(),
type: 'bar',
value: 789,
date: '2022-06-27',
}, {
_id: new ObjectId(),
type: 'baz',
value: 234,
date: '2022-06-26',
},
// etc....
]

按日期排序。

我想获得前两种类型中出现的所有最前面的项。在本例中,这意味着我想获得显示的最后一项上面的所有内容,该项类型为"baz",是在"foo"类型之后存在的第三种类型。和"bar".

// Expected result
[{
_id: new ObjectId(),
type: 'foo',
value: 123,
date: '2022-06-30',
}, {
_id: new ObjectId(),
type: 'bar',
value: 321,
date: '2022-06-29',
}, {
_id: new ObjectId(),
type: 'foo',
value: 456,
date: '2022-06-28',
}, {
_id: new ObjectId(),
type: 'bar',
value: 789,
date: '2022-06-27',
}]

假设这个新项被添加到集合中:

{
_id: new ObjectId(),
type: 'baz',
value: 567,
date: '2022-07-01',
}

新的预期结果将是

[{
_id: new ObjectId(),
type: 'baz',
value: 567,
date: '2022-07-01',
}, {
_id: new ObjectId(),
type: 'foo',
value: 123,
date: '2022-06-30',
}]

…作为"bar"from2022-06-29现在是第三个出现在有序集中的类型。

从mongoDB版本5.0开始,您可以使用$setWindowFields:

  1. $setWindowFields允许根据date进行排序,并为每个文档添加一个新字段,其中包含一组types"到目前为止"。
  2. 现在我们只需要匹配少于3个topTypes的文档。
db.collection.aggregate([
{
$setWindowFields: {
sortBy: {date: -1},
output: {
topTypes: {
$addToSet: "$type",
window: {documents: ["unbounded", "current"]}
}
}
}
},
{
$match: {$expr: {$lt: [{$size: "$topTypes"}, 3]}}
},
{
$unset: "topTypes"
}
])

看看它在操场的例子中是如何工作的

相关内容

  • 没有找到相关文章

最新更新