查询MongoDB中的地图大小

时间:2015-10-27 15:44:07

标签: mongodb

假设您在mongodb中有一个可变大小的地图。 如何获得仅具有特定地图大小的文档,例如> 2?

    NA.Count = function(x)
    {
        return(sum(is.na(x)))
    }

Row.NA.Count = apply(MAT,1,NA.Count)

Idx = Row.NA.Count == ncol(MAT)

MAT = MAT[!Idx,]

1 个答案:

答案 0 :(得分:2)

使用MongoDB 3.6及更高版本:

在查询中使用 $expr 运算符,这允许您使用聚合框架运算符,尤其是转换地图的 $objectToArray 运算符subocument到一组键值,即

{ map: {
    k1:v1, 
    k2:v2, 
    k3,v3
}}

转换为数组

{ map: [
    { k: 'k1', v: 'v1' }, 
    { k: 'k2', v: 'v2' }, 
    { k: 'k3', v: 'v3' }
]}

使用数组,您可以使用$ size来获取长度,并使用比较查询运算符 $gt 进行比较。

下面的示例显示了完整的查询:

db.test.find({
    "$expr": {
        "$gt": [
            { "$size": { "$objectToArray": "$map" } },
            2
        ]
    }
})

对于不支持上述运算符的MongoDB版本,如果您想稍后对它们进行查询,则需要预先计算此类地图大小,因此请考虑创建一个新字段"keyCount"保存地图子文档的键数。请考虑以下演示:

填充测试集合

db.test.insert([    
    {   
        "_id" : 1,  
        "map" : {
            "k1" : "v1",
            "k2" : "v2",
            "k3" : "v3"
        }
    },
    {       
        "_id" : 2,
        "map" : {
            "k1" : "v1",
            "k2" : "v2"
        }
    }
 ]);

与当前设计一样,您需要一种机制来获取地图文档中所有键的计数。这可以通过 Map-Reduce 来实现。以下mapreduce操作将使用添加的新字段"keyCount"填充单独的集合:

var mr = db.runCommand({
    "mapreduce": "test",
    "map" : function() {
        var obj = this;
        obj['keyCount'] = Object.keys(this.map).length;
        emit(this._id, obj); 
    },
    "reduce" : function(key, stuff) { return null; }, 
    "out": "my_collection" + "_keys"
})

要获取仅具有特定地图大小的文档,例如> 2,请对生成的集合运行查询:

db[mr.result].find({ "value.keyCount": { "$gt": 2 } });

映射减少输出

/* 0 */
{
    "result" : "my_collection_keys",
    "timeMillis" : 7,
    "counts" : {
        "input" : 2,
        "emit" : 2,
        "reduce" : 0,
        "output" : 2
    },
    "ok" : 1
}

查询输出

/* 0 */
{
    "_id" : 1,
    "value" : {
        "_id" : 1,
        "map" : {
            "k1" : "v1",
            "k2" : "v2",
            "k3" : "v3"
        },
        "keyCount" : 3
    }
}