MongoDB如何按键数组(非值)过滤?

MongoDB如何按键数组(非值)过滤?,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为的用户:数组('111','333')

我只会得到以下方案中的一些字段(名称)的用户与这些ID

    {
        "_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