gpt4 book ai didi

javascript - 按已过滤子文档数组元素的计数排序

转载 作者:行者123 更新时间:2023-11-27 23:44:27 25 4
gpt4 key购买 nike

我目前有一个 MongoDB 集合,如下所示:

{
{
"_id": ObjectId,
"user_id": Number,
"updates": [
{
"_id": ObjectId,
"mode": Number,
"score": Number
},
{
"_id": ObjectId,
"mode": Number,
"score": Number
},
{
"_id": ObjectId,
"mode": Number,
"score": Number
}
]
}
}

我正在寻找一种方法来查找每种模式更新次数最多的用户。例如,如果我指定模式 0,我希望它按照 mode: 0 的最大更新次数顺序加载用户。

这在 MongoDB 中可能吗?它不需要是一个快速的算法,因为它会被缓存相当长的一段时间,并且它将异步运行。

最佳答案

最快的方法是将文档中每个“模式”的计数存储为另一个字段,然后您可以对其进行排序:

var update = { 
"$push": { "updates": updateDoc },
};

var countDoc = {};
countDoc["counts." + updateDoc.mode] = 1;

update["$inc"] = countDoc;

Model.update(
{ "_id": id },
update,
function(err,numAffected) {

}
);

这将使用 $inc为每个“模式”值增加一个“计数”字段,作为推送到“更新”数组的每个“模式”的键。所有计算都在更新时进行,因此速度很快,并且可以对该值进行排序的查询也很快:

Model.find({ "updates.mode": 0 }).sort({ "counts.0": -1 }).exec(function(err,users) {

});

如果您不想或无法存储此类字段,则另一个选项是在查询时使用 .aggregate() 进行计算:

Model.aggregate(
[
{ "$match": { "updates.mode": 0 } },
{ "$project": {
"user_id": 1,
"updates": 1,
"count": {
"$size": {
"$setDifference": [
{ "$map": {
"input": "$updates",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.mode", 0 ] },
"$$el",
false
]
}
}},
[false]
]
}
}
}},
{ "$sort": { "count": -1 } }
],
function(err,results) {

}
);

这还不错,因为过滤了数组并得到 $size相当有效,但不如仅使用存储值那么快。

$map运算符允许内联处理 $cond 测试的数组元素查看它是否返回匹配项或 false。然后$setDifference删除任何错误值。这是比使用 $unwind 更好的过滤数组内容的方法,它会显着减慢速度,除非您打算跨文档聚合数组内容,否则不应使用。

但更好的方法是存储计数值,因为这不需要运行时计算,甚至可以使用索引

关于javascript - 按已过滤子文档数组元素的计数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33357790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com