有没有一种方法可以预测字段的类型 [英] Is there a way to project the type of a field
问题描述
假设我们有类似以下文档的内容,但是我们只想返回包含数字信息的字段:
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:
- 由于查询是进行投射的能力中的一个独特参数,因此单独使用单个查询是不可能的,因为投射不会受到查询结果的影响
- 由于聚合框架无法迭代字段和检查类型,因此这也不是一种选择
话虽这么说,但是使用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屋!