Mongodb 动态mongo投影-使用文档中的字段确定投影的投影
假设我有一个这样的物体:Mongodb 动态mongo投影-使用文档中的字段确定投影的投影,mongodb,projection,Mongodb,Projection,假设我有一个这样的物体: {default: 'x', types: { x:1, y:2, z:3 } } var mapper = function() { var typeValue = this.types[this.default], typeKey = "types." + this.default; emit(this._id, { key : typeKey, val : typeValue } ); }; 是否可以只选
{default: 'x',
types: {
x:1,
y:2,
z:3
}
}
var mapper = function() {
var typeValue = this.types[this.default],
typeKey = "types." + this.default;
emit(this._id, { key : typeKey, val : typeValue } );
};
是否可以只选择types.x(即
{“types.x”:1}
)而事先不知道x是默认值?进行两次查询显然是可能的,而不是我想要的。不幸的是,这还不是聚合框架的一部分。然而,据报道,这是目前“计划的,而不是预定的”。目前唯一的方法是使用map/reduce功能。如果你想继续使用它,就意味着要做以下事情:
var mapper = function() {
var typeValue = this.types[this.default];
emit(this._id, typeValue);
};
var reducer = "";
db.types.mapReduce(mapper, reducer, { out : "results" } );
> db.results.find();
{ "_id" : ObjectId("53d21a270dcfb83c7dba8da9"), "value" : 1 }
> db.results.find().pretty();
{
"_id" : ObjectId("53d21a270dcfb83c7dba8da9"),
"value" : {
"key" : "types.x",
"val" : 1
}
}
mongo
shell中,它看起来如下所示:
var mapper = function() {
var typeValue = this.types[this.default];
emit(this._id, typeValue);
};
var reducer = "";
db.types.mapReduce(mapper, reducer, { out : "results" } );
> db.results.find();
{ "_id" : ObjectId("53d21a270dcfb83c7dba8da9"), "value" : 1 }
> db.results.find().pretty();
{
"_id" : ObjectId("53d21a270dcfb83c7dba8da9"),
"value" : {
"key" : "types.x",
"val" : 1
}
}
如果随后查询结果集合,您将得到如下结果:
var mapper = function() {
var typeValue = this.types[this.default];
emit(this._id, typeValue);
};
var reducer = "";
db.types.mapReduce(mapper, reducer, { out : "results" } );
> db.results.find();
{ "_id" : ObjectId("53d21a270dcfb83c7dba8da9"), "value" : 1 }
> db.results.find().pretty();
{
"_id" : ObjectId("53d21a270dcfb83c7dba8da9"),
"value" : {
"key" : "types.x",
"val" : 1
}
}
如果您想知道默认值是什么,可以修改mapper
函数,以便将键作为值返回。它看起来像这样:
{default: 'x',
types: {
x:1,
y:2,
z:3
}
}
var mapper = function() {
var typeValue = this.types[this.default],
typeKey = "types." + this.default;
emit(this._id, { key : typeKey, val : typeValue } );
};
运行时,将产生如下结果:
var mapper = function() {
var typeValue = this.types[this.default];
emit(this._id, typeValue);
};
var reducer = "";
db.types.mapReduce(mapper, reducer, { out : "results" } );
> db.results.find();
{ "_id" : ObjectId("53d21a270dcfb83c7dba8da9"), "value" : 1 }
> db.results.find().pretty();
{
"_id" : ObjectId("53d21a270dcfb83c7dba8da9"),
"value" : {
"key" : "types.x",
"val" : 1
}
}
请注意,这可能是一个比您想要的复杂得多的解决方案,但这是使用MongoDB而不向应用程序添加更多逻辑的唯一方法。谢谢您的回答。相比之下,我必须运行两个常规查询才能获得相同的效果,您知道这两个查询的性能是什么吗?还是运行一个选择所有类型的查询的性能?@BT,我不建议您使用Map/Reduce进行实时聚合。解释了其中的一些原因。如果不能更改模式,我认为最好的选择是运行两个常规查询。此外,您肯定应该推动实现我上面复制的JIRA票据中的功能。在社区的压力下,它可能会在未来版本的MongoDB中实现。希望早点儿,谢谢你提供的好消息。我会把我的评论添加到列表中这些白痴是谁投票来结束这样的问题?完全没有必要。嘿,白痴:当你投票结束某件事的时候,写一篇关于为什么的评论。如果你是对的,那么也许OP会在将来避免类似的问题。如果你错了,我们都会看到你的推理有多愚蠢。我认为这是公平的交易。每个文件都有自己的默认值吗?基于这一点,你想让这片区域被投影吗?所有可能的默认值都是预先知道的吗?想想看,如果您的模式不同(如果您将类型存储为带有{type:“x”,value:1}的数组),那么您可以使用聚合框架来实现这一点元素类型。嗯,有趣的想法。我很惊讶聚合框架不能处理关键字。每个文档都有自己的默认值,是的。默认值的可能值事先不知道。