按过滤后的子文档数组元素的数量排序

汤姆森

我目前有一个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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

按过滤后的子文档数组元素计数

来自分类Dev

按元素推入子文档数组

来自分类Dev

按与过滤器匹配的数组的最后一个元素中的值对文档进行排序。Mongodb

来自分类Dev

MongoDB按数组元素对文档进行排序

来自分类Dev

在 Mongoose 中过滤子文档数组并仅返回匹配的元素

来自分类Dev

按匹配的子文档排序

来自分类Dev

按数组元素排序

来自分类Dev

按数组的元素排序

来自分类Dev

Ruby按子元素对数组进行排序

来自分类Dev

Ruby按子元素对数组进行排序

来自分类Dev

如何过滤子文档数组?

来自分类Dev

Python 和排序:按数组中的子元素对元素进行排序

来自分类Dev

按子数组过滤

来自分类Dev

按数量属性过滤对象数组

来自分类Dev

MongoDB聚合-按子文档过滤

来自分类Dev

按日期时间过滤子文档

来自分类Dev

MongoDB,按两个数组之间匹配元素的数量对结果进行排序

来自分类Dev

MongoDB:按名称未知的子文档排序

来自分类Dev

MongoDB-按子文档匹配排序

来自分类Dev

在mongo中按子文档字段排序

来自分类Dev

按子文档数目mongoid排序

来自分类Dev

如何按子文档的字段总和排序

来自分类Dev

Mongo按对象数组过滤文档

来自分类Dev

Mongodb:按数组最后一个元素中的值对文档进行排序

来自分类Dev

在聚合mongodb中按文档数组排序

来自分类Dev

按某些条件过滤数组的子数组

来自分类Dev

按数组元素对数组进行排序

来自分类Dev

按自然索引访问文档的子元素

来自分类Dev

MongoDB按字段分组以用于子文档中的不同数组元素