0

I have a collection of contacts with the following structure:

{
    "_id": "58f969646320ef4b5171dfe2",
    "user_id": 1170,
    "others": {
        "campaigns": [
            {
                "campaign_id": 111,
                "is_attendee": true,
                "score": 25,
            },
            {
                "campaign_id": 112,
                "is_attendee": false,
                "score": 22,
            }

        ]
    },
}

I want to return the contacts who belong to user 1170 but projecting only the first campaigns which have the ID in [111, 119] so I made the following query:

db.contacts.find({
    "others.campaigns.user_id": 1170
}, {
    "others.campaigns": {
        $elemMatch: {
            "campaign_id": {$in: [111, 119]}
        }
    },
    {
        "others.campaigns.$": 1
    }
).limit(1).pretty()

but I got this error:

error: {
    "ok" : 0,
    "errmsg" : "Cannot use $elemMatch projection on a nested field.",
    "code" : 2,
    "codeName" : "BadValue"
}

So, is there any way to make the query work successfully?

Please: Discard the aggregation framework as a possible solution.

Delmo
  • 2,188
  • 2
  • 20
  • 29
  • Are both the `111` and `119` matching elements within the same document, but just different members of the array? If so then the aggregation framework **is the only way** you can actually just return those multiple elements of the array. Why do you say discard it? As in what do you think is so bad about it? Using `$unwind` would not be optimal, but modern versions have other operators that do not require that. Such as `$filter` for this particular case. Your solution is a simple `$match` and `$project`, and every bit as fast as a general `.find()`. – Neil Lunn May 25 '17 at 23:44
  • Thanks, @NeilLunn. Yes, they are. There could be two different campaigns, one with the ID 111 and the other with the ID 119. I am trying to improve the performance of several so I guessed that aggregation framework could be a little slower than a simple find and projection but ok, I will try with aggregation to compare results. – Delmo May 25 '17 at 23:59
  • Well there should be an answer on that page showing `$project` with `$filter`. If not, then I'll add one there. But as I said a simple two pipelines of `$match` and `$project` is exactly what "find" and "project" is doing, with almost no difference in overhead. – Neil Lunn May 26 '17 at 00:03
  • You marked this question as duplicated but the supposed original question is not exactly as this, even though the answer could be similar. I don't want to get only some fields of the array element as @Sebtm asked. My issue is the nested field (`others.campaigns`) so with the @Sebtm's structure I would not have this issue. – Delmo May 26 '17 at 00:04

0 Answers0