$ elemMatch和$ in能正常协同工作吗?

时间:2015-10-01 21:02:37

标签: node.js mongodb mongoose

修改 这是我的架构:

{
    "_id": "salfjasdlkfjaslkdfj",
    "data": [
        {
            "title": "data1",
            "_id": "xxx",
            //more fields
        },
        {
            "title": "data2",
            "_id": "yyy",
            //more fields
        },
        {
            "title": "data3",
            "_id": "zzz",
            //more fields
        }
    ],
    //more fields
}

我在mongoose中的查询看起来像这样:

mySchema.findOne(
    id,
    {"data": {$elemMatch: {"_id": {$in: ["xxxxx", "yyyyy"]}}}},
    {},
    function(err, data){
        if(err){
            console.log(err);
            res.send(err);
            return;
        }
        res.json(data);
    }
);

我想从“data”数组中投射2个或更多元素。但是,使用此代码,结果始终只包含“data”中的一个元素,即使“$ in”之后的数组包含2个或更多元素。

如果没有“$ in”(也就是说,只从“数据”数组中投射一个元素),这种方法非常好。

根据https://jira.mongodb.org/browse/SERVER-3544,$ elemMatch和$ in应该相互协作。

  • 我的代码有问题吗?
  • 如果$ elemMatch和STILL中的$不能相互协作,是否有另一种方式来投射它?

修改 预期的输出是:

{
    "_id": "salfjasdlkfjaslkdfj",
    "data": [
        {
            "title": "data1",
            "_id": "xxx",
            //more fields
        },
        {
            "title": "data2",
            "_id": "yyy",
            //more fields
        },
    ]
}

我刚试过这个查询,但它给了我一个空数组! “[]”。 我想我在某处弄乱了语法,或者其他东西。我不确定。

mySchema.aggregate(
    [
            {$match: {"_id": id}},
            {$unwind: "$data"},
            {$match: {"data._id": {$in: ["xxx", "yyy"]}}},
            {$project: {"data":1}}
    ],
    function(err, data){
        if(err){
            console.log(err);
            res.send(err);
            return;
        }
        res.json(data);
    }
);

1 个答案:

答案 0 :(得分:0)

最后我发现了问题! “id”是String格式,我需要以ObjectId()格式解析它。这是工作代码:

for(var i=0;i<array.length;i++){
    array[i] = mongoose.Types.ObjectId(array[i]);
}

mySchema.aggregate(         
    [
        {$match: {"_id": mongoose.Types.ObjectId(id)}},
        {$unwind: "$data"},
        {$match: {"data._id": {$in: array}}},
        {$group: {"_id": "$_id", "data": { $push: '$data' }}},
        {$project: {"data": 1}}
    ],
    function(err, data){
        if(err){
            console.log(err);
            res.send(err);
            return;
        }
        res.json(data);
    }
);