MongoDB如何按键数组(非值)过滤?
我有一个带有用户密钥的数组 id为的用户:数组('111','333') 我只会得到以下方案中的一些字段(名称)的用户与这些IDMongoDB如何按键数组(非值)过滤?,mongodb,mongodb-query,aggregation-framework,mongodb-php,Mongodb,Mongodb Query,Aggregation Framework,Mongodb Php,我有一个带有用户密钥的数组 id为的用户:数组('111','333') 我只会得到以下方案中的一些字段(名称)的用户与这些ID { "_id" : "78787878", "users" : { "111" : { "name" : "William", "e" : "w@sas..." ... },
{
"_id" : "78787878",
"users" : {
"111" : {
"name" : "William",
"e" : "w@sas..."
...
},
"222" : {
"name" : "Sarah",
"e" : "s@sas..."
},
"333" : {
"name" : "Marie",
"e" : "m@sas..."
},..
},..
}
我的预期结果如下:
{
"_id" : "78787878",
"users" : {
"111" : {
"name" : "William",
},
"333" : {
"name" : "Marie",
}
}
}
我试过:
db.getCollection('instagram').find({'_id' : '78787878', 'users' : { '$in' : ['456726', '2945551665'] } }, { '_id' : 0, 'users.name' : 1 })
如何进行此类查询?我可以用“findOne”还是应该用“aggregate”?
编辑(问题继续):
根据注释,如果我修改模式如下:
{
"_id" : "78787878",
"users" : [
{
"id": 111,
"name" : "William",
"e" : "w@sas..."
...
},
{
"id": 222,
"name" : "Sarah",
"e" : "s@sas..."
},
{
"id": 333,
"name" : "Marie",
"e" : "m@sas..."
},..
]
}
如果我在中使用$,它将返回所有。。。为什么不应用过滤器
$filter = array(111, 333);
$this->db->{$collection}->find(array('_id' => '78787878', 'users.id' => array('$in' => $filter)), array('users' => 1));
users.id是Int32。您可能希望像这样重新构造数据
{
"_id" : "78787878",
"users" : [
{
"id": "111",
"name" : "William",
"e" : "w@sas..."
...
},
{
"id": "222",
"name" : "Sarah",
"e" : "s@sas..."
},
{
"id": "333",
"name" : "Marie",
"e" : "m@sas..."
},..
]
}
然后您可以像这样轻松地查询它
db.instagram.find({'users.id':{$in: ['111', '333']}})
对于这样的模式,如果您有散列键,则很难进行查询,除非您可以对其进行更改,以便将用户ID嵌入到数组中 然而,对于这种结构,唯一可用的选项是通过投影获得所需的输出。您需要一种机制来构造投影,如下面的查询所示
db.instagram.find(
{ "_id": "78787878"},
{ "users.111": 1, "users.333": 1 }
);
这将产生所需的输出
{
"_id" : "78787878",
"users" : {
"111" : {
"name" : "William",
"e" : "w@sas..."
},
"333" : {
"name" : "Marie",
"e" : "m@sas..."
}
}
}
因此,给定只希望投影的带有用户ID的输入数组,可以通过JavaScript的函数构造投影文档,从而将数组简化为对象。
考虑下面的方法来创建上面的查询:
var userIds = ['111', '333'],
query = { "_id": "78787878"},
projection = userIds.reduce(function(o, v, i) {
o["users."+v] = 1;
return o;
}, {});
db.instagram.find(query, projection)
我已经应用了新的模式,但查询仍然无法运行。您是否使用mongo shell进行了尝试?或者其他mongoDB客户端?我也在“Robomongo”中尝试了查询,结果仍然没有过滤。查询:db.getCollection('mycollection').find({'u id':'787878','users.id':{'in':[111333]},},{'users':1})我已经应用了新的模式,但查询仍然对我无效。@ephramd您更改了什么模式?上面的查询只适用于问题中的原始模式。我编辑了问题(在编辑结束时)。我尝试应用最简单的没有散列键的结构。您使用哪个MongoDB版本?我使用MongoDB 1.6.12和PHP5.6.17