使用MongoDB框架将键盘映射转换为矢量 [英] Transform keymap into vector using MongoDB framework

查看:118
本文介绍了使用MongoDB框架将键盘映射转换为矢量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MongoDB的x集合中有这样的文档:

I have documents like this one at collection x at MongoDB:

{
    "_id" : ...
    "attrKeys": [ "A1", "A2" ],
    "attrs" : {
        "A1" : {
            "type" : "T1",
            "value" : "13"
        },
        "A2" : {
            "type" : "T2",
            "value" : "14"
        }
    }
}

上面的A1A2元素仅是示例:attrs字段可以容纳任意数量的任何名称的键. attrs中的键名存储在attrNames字段中.

The A1 and A2 elements above are just examples: the attrs field may hold any number of keys of any name. The key names in attrs are stored in the attrNames field.

我想使用MongoDB聚合框架将该文档转换为这样的文档:

I would like to use the MongoDB aggregation framework to transform that document into one like this:

{
    "_id" : ...
    "attrs" : [
        {   
            "key": "A1",
            "type" : "T1",
            "value" : "13"
        },
        {   
            "key": "A2",
            "type" : "T2",
            "value" : "14"
        }
    ]
}

也就是说,要成为数组中的attrs,这些元素与键值将键传递"到名称为key的每个数组元素内的新字段中的元素相同.

That is, to become attrs into an array, which elements are the same that the key values "passing" the key into a new field inside each array element of name key.

是否可以使用聚合框架进行吮吸转换?我倾向于认为可以使用$project运算符,但是我还没有弄清楚该怎么做.

It is possible use the aggregation framework for suck transformation? I tend to think that $project operator could be used, but I haven't figured out how.

推荐答案

聚合框架不是您在此处处理转换的方式.您可能一直希望$out运算符在重新编写集合时会有所帮助,但是聚合框架无法满足您的要求.

The aggregation framework is not how you handle the transformation here. You might have been looking to the $out operator to be of some help when re-writing your collection, but the aggregation framework cannot do what you are asking.

基本上,聚合框架缺少通过任何方式使用数据点"动态访问密钥"的方法.您可以像使用mapReduce一样处理数据,但是它通常不如使用聚合框架有效,并且主要是为什么您似乎首先出现在这里,因为有人指出修改后的结构更好.

Basically the aggregation framework lacks the means to access "keys" dynamically by using a "data point" in any way. You can process data like you have with mapReduce, but it is generally not as efficient as using the aggregation framework and mostly why you seem to be here in the first place, since someone pointed out the revised structure is better.

此外,尝试使用mapReduce作为重塑"集合以进行存储的方法通常也不是一个好主意. MapReduce输出本质上是始终"键/值",这意味着您获得的输出将始终包含在必填的值"字段中.

Also, trying to use mapReduce as a way to "re-shape" your collection for storage is generally not a good idea. MapReduce output is essentially "always" "key/value", which means the output you get is always going to be contained under an mandatory "value" field.

这实际上意味着更改集合的内容,并且在使用文档中存在的值时真正做到这一点的唯一方法是读取"文档内容,然后写回".

This really means changing the contents of the collection, and the only way you can really do that while using the values present in you document is by "reading" the document content and then "writing" back.

使用批量" 操作API方法

db.collection.intializeOrderedBukOp(),
var bulk = db.collection.intializeOrderedBukOp(),
    count = 0;

db.collection.find({ "attrKeys": { "$exists": true }}).forEach(function(doc) {
   // Re-map attrs
   var attrs = doc.attrKeys.map(function(key) {
       return {
           "key": key,
           "type": doc.attrs[key].type,
           "value": parseInt(doc.attrs[key].value)
       };
   });

   // Queue update operation
   bulk.find({ "_id": doc._id, "attrKeys": { "$exists": true } })
       .updateOne({ 
           "$set": { "attrs": attrs },
           "$unset": { "attrKeys": 1 }
       });
   count++;

   // Execute every 1000
   if ( count % 1000 == 0 ) {
       bulk.execute();
       bulk = db.collection.intializeOrderedBukOp();
   }
});

// Drain any queued remaining
if ( count % 1000 != 0 )
    bulk.execute();

一旦您更新了集合内容(请注意,您的值"字段也已从字符串"更改为整数"格式),则可以对新结构执行有用的聚合操作,例如:

Once you have updated the collection content ( and please note that your "value" fields there have also been changed from "string" to "integer" format ) then you can do useful aggregation operations on your new structure, such as:

db.collection.aggregate([
    { "$unwind": "$attrs" },
    { "$group": {
        "_id": null,
       "avgValue": { "$avg": "$attrs.value" }
    }}
])

这篇关于使用MongoDB框架将键盘映射转换为矢量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆