我目前有一个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
,过滤数组内容的方法要好得多,这可能会大大降低速度,因此除非您打算在整个文档中聚集数组内容,否则不应该使用它。
但是更好的方法是存储计数的值,因为这不需要运行时计算,甚至可以使用索引
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句