MongoDB -根据频率获取文档的排名


[
{_id: 1, query: 'A', createdAt: 1660610671 },
{_id: 2, query: 'A', createdAt: 1660610672 },
{_id: 3, query: 'A', createdAt: 1660610673 },
{_id: 4, query: 'A', createdAt: 1660610674 },
{_id: 5, query: 'B', createdAt: 1660610675 },
{_id: 6, query: 'C', createdAt: 1660610676 },
{_id: 7, query: 'C', createdAt: 1660610677 },
{_id: 8, query: 'C', createdAt: 1660610678 },
{_id: 9, query: 'D', createdAt: 1660610680 },
{_id: 10, query: 'D', createdAt: 1660610681 },
]

我有上面的数据库结构。我想从特定时期query值的频率中获得排名。

可能是这样的。

Queries.getRank({ key: 'query', createdAt: {$gte: startUnix, $lt: endUnix } }) 

我期望结果如下。

排名
[
{rank: 1, query: 'A', frequency: 4},
{rank: 2, query: 'C', frequency: 3},
{rank: 3, query: 'D', frequency: 2},
{rank: 4, query: 'B', frequency: 1}
]

有办法实现吗?谢谢。

  1. $match-createdAt字段范围内的过滤文档(如果需要)。

  2. $group-将query分组,将$count作为frequency执行。

  3. $project-修饰输出文档。

  4. $setWindowFields-与$rank一起按frequency降序排序。可以考虑对具有相同等级的文档使用$denseRank

db.collection.aggregate([
// $match stage
{
$group: {
_id: "$query",
frequency: {
$sum: 1
}
}
},
{
$project: {
_id: 0,
query: "$_id",
frequency: "$frequency"
}
},
{
$setWindowFields: {
partitionBy: null,
sortBy: {
frequency: -1
},
output: {
rank: {
$rank: {}
}
}
}
},

])

Demo @ Mongo Playground

您可以编写以下聚合管道:

db.collection.aggregate([
{
"$group": {
"_id": "$query",
"frequency": {
"$sum": 1
}
}
},
{
"$project": {
"query": "$_id",
"frequency": 1,
"_id": 0
}
},
{
"$sort": {
frequency: -1
}
},
{
"$group": {
"_id": null,
"array": {
"$push": "$$ROOT"
}
}
},
{
"$unwind": {
path: "$array",
"includeArrayIndex": "rank"
}
},
{
"$project": {
_id: 0,
rank: {
"$add": [
"$rank",
1
]
},
frequency: "$array.frequency",
query: "$array.query"
}
}
]);

操场上链接。

在这里,我们首先计算每个查询的频率,然后按频率对其排序,最后,我们将所有文档推入数组并使用数组索引计算排名。

相关内容

  • 没有找到相关文章

最新更新