假设我们有类似下面的文档,但我们只想返回包含数字信息的字段:
{
"_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
}
现在我知道我们可以使用$type运算符查询匹配特定类型的字段。但我还是偶然发现了将此作为一个字段值的方法。因此,如果我们以“展开”的形式查看文档,您会看到:
{
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"name" : 2,
"list" : 16,
"people" : 2
"status" : 8,
"created" : 9,
"views" : 16
}
最终目标是仅列出匹配某种类型的字段,假设比较得到数字类型并过滤掉字段,经过多次文档修改后,产生如下结果:
{
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"list" : [ 1, 2, 3, 4, 5 ],
"views" : 5
}
有没有人有办法解决这个问题。
答案 0 :(得分:2)
有一些问题使得这不切实际:
话虽如此,有一种使用Map-Reduce的方式有点令人讨厌的方法可以得到类似的答案,尽管Map-Reduce样式输出并不令人敬畏:
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;
};
它不完整,但结果与您想要的结果类似:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
地图只是查看每个属性并确定它是否看起来像一个数字......如果是这样,添加到将存储为对象的数组,以便map-reduce引擎不会阻塞数组输出。我在示例代码中保持简单 - 您可以确保数字和数组检查的逻辑。 :)
当然,它不像find
或聚合一样存在,但由于MongoDB的设计并未考虑到这一点,如果你真的想要这个功能,可能需要这样做。