有没有一种方法可以预测字段的类型 [英] Is there a way to project the type of a field

查看:101
本文介绍了有没有一种方法可以预测字段的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有类似以下文档的内容,但是我们只想返回包含数字信息的字段:

Suppose we had something like the following document, but we wanted to return only the fields that had numeric information:

{
    "_id" : ObjectId("52fac254f40ff600c10e56d4"),
    "name" : "Mikey",
    "list" : [ 1, 2, 3, 4, 5 ],
    "people" : [ "Fred", "Barney", "Wilma", "Betty" ],
    "status" : false,
    "created" : ISODate("2014-02-12T00:37:40.534Z"),
    "views" : 5
}

现在,我知道我们可以使用

Now I know that we can query for fields that match a certain type by use of the $type operator. But I'm yet to stumble upon a way to $project this as a field value. So if we looked at the document in the "unwound" form you would see this:

{
    "_id" : ObjectId("52fac254f40ff600c10e56d4"),
    "name" : 2,
    "list" : 16,
    "people" : 2
    "status" : 8,
    "created" : 9,
    "views" : 16
}

最终目标是仅列出与匹配特定类型的字段,例如,进行比较以获取数字类型并经过大量文档处理后过滤掉这些字段,以产生如下结果:

The final objective would be list only the fields that matched a certain type, let's say compare to get the numeric types and filter out the fields, after much document mangling, to produce a result as follows:

{
    "_id" : ObjectId("52fac254f40ff600c10e56d4"),
    "list" : [ 1, 2, 3, 4, 5 ],
    "views" : 5
}

有人能解决这个问题吗?

Does anyone have an approach to handle this.

推荐答案

有一些问题使其不切实际:

There are a few issues that make this not practical:

  1. 由于查询是进行投射的能力中的一个独特参数,因此单独使用单个查询是不可能的,因为投射不会受到查询结果的影响
  2. 由于聚合框架无法迭代字段和检查类型,因此这也不是一种选择

话虽这么说,但是使用Map-Reduce的确有点怪异的方法,尽管它的Map-Reduce样式输出效果不佳,但确实得到了类似的答案:

That being said, there's a slightly whacky way of using a Map-Reduce that does get similar answers, albeit in a Map-Reduce style output that's not awesome:

map = function() {
    function isNumber(n) {
      return !isNaN(parseFloat(n)) && isFinite(n);
    }

    var numerics = [];
    for(var fn in this) {
        if (isNumber(this[fn])) {
            numerics.push({f: fn, v: this[fn]});
        }
        if (Array.isArray(this[fn])) {
            // example ... more complex logic needed
            if(isNumber(this[fn][0])) {
                numerics.push({f: fn, v: this[fn]});
            }
        }
    }
    emit(this._id, { n: numerics });
};

reduce = function(key, values) {
  return values;  
};

它还不完整,但是结果与您想要的类似:

It's not complete, but the results are similar to what you wanted:

"_id" : ObjectId("52fac254f40ff600c10e56d4"),
 "value" : {
         "n" : [
                 {
                         "f" : "list",
                         "v" : [
                                 1,
                                 2,
                                 3,
                                 4,
                                 5
                         ]
                 },
                 {
                         "f" : "views",
                         "v" : 5
                 }
         ]
 }

地图只是查看每个属性并确定它是否看起来像数字...如果是,则将其添加到将存储为对象的数组中,以使地图缩减引擎不会在数组上阻塞输出.在示例代码中,我将其简化了-您可以肯定地改善数字和数组检查的逻辑. :)

The map is just looking at each property and deciding whether it looks like a number ... and if so, adding to an array that will be stored as an object so that the map-reduce engine won't choke on array output. I've kept it simple in the example code -- you could improve the logic of numeric and array checking for sure. :)

当然,它不是像find或聚合那样运行的,但是由于MongoDB并不是在设计时考虑到这一点的,因此,如果您确实想要此功能,则可能必须这样做.

Of course, it's not live like a find or aggregation, but as MongoDB wasn't designed with this in mind, this may have to do if you really wanted this functionality.

这篇关于有没有一种方法可以预测字段的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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