【问题标题】:Query the map size in MongoDB在MongoDB中查询地图大小
【发布时间】:2018-04-04 03:16:46
【问题描述】:

假设你在 mongodb 中有一张可变大小的地图。 如何获取只有特定地图大小的文档,例如 >2?

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

【问题讨论】:

  • 我不相信有一个内置函数可以让您获得对象中的键数。您必须查询每个文档,然后自己计算键的数量。让我知道我是否正确阅读了您的问题。 stackoverflow.com/questions/8980145/…

标签: mongodb


【解决方案1】:

使用 MongoDB 3.6 及更高版本:

在查询中使用 $expr 运算符,这允许您使用聚合框架运算符,特别是 $objectToArray 运算符,它将地图子文档转换为数组关键值,即

{ 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
    }
}

【讨论】:

    猜你喜欢
    • 2020-10-15
    • 1970-01-01
    • 2011-10-07
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多