0

I'm trying to return a specific collection, however, I want to filter an array within the collection. I'm not sure if this is possible. In the example below I'm trying to return the collection with _id: 7ARk3dc2JA8g5pamA and filter out the array object for "candidateUserId": "2". I'm doing this in a Meteorjs application.

Eg: `Collection'

{
  "_id": "7ARk3dc2JA8g5pamA",
  "jobTitle": "Developer",
  "candidateApplication": [
    {
      "candidateUserId": "1",
      "applied": true
    },
    {
      "candidateUserId": "2",
      "applied": false
    }
  ]
}

Path: Publish command

return Jobs.find({ _id: 7ARk3dc2JA8g5pamA }, {
  $filter: {
    input: candidateApplication,
    cond: { candidateUserId: { $eq: 1 } }
  }
});
bp123
  • 2,756
  • 4
  • 22
  • 53
  • [`$filter`](https://docs.mongodb.com/manual/reference/operator/aggregation/filter/) is an operator for use with `.aggregate()` and **not** `.find()`. So you are using it in the wrong place. – Neil Lunn Oct 17 '17 at 02:31
  • @NeilLunn Could you explain how I do this then? – bp123 Oct 17 '17 at 02:37
  • 1
    Which part of [Retrieve only the queried element in an object array in MongoDB collection](https://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) do you not understand? You seem to have read something that pointed you to `$filter`. The documentation of the operator ( linked ) and the very common question and answers ( linked ) all clearly show how to use with `.aggregate()`. You have a `$match` stage for the query and either `$project` or `$addFields` as required for the projection in "filtering" the array. – Neil Lunn Oct 17 '17 at 02:40
  • Also note that as "other" answers on the same question supply, if you only need **one** result from the array then standard positional projection is all that is neeed. i.e `.find({ { _id: '7ARk3dc2JA8g5pamA', "candidateApplication.candidateUserId": 1 }, { "fields": { "candidateApplication.$": 1 } })`. Using `"fields"` as the meteor specific thing I think. – Neil Lunn Oct 17 '17 at 02:41

1 Answers1

0
Jobs.find({ _id: 7ARk3dc2JA8g5pamA }, { candidateApplication: { $elemMatch: { candidateUserId: 2 } } }

This should return the document with only the _id and the candidateUserId array, but that array will now only contain the object that you want.

{ "_id" : 7ARk3dc2JA8g5pamA, "candidateApplication" : [ { "candidateUserId": 2, "applied": false } ] } 

You can then get to the data with candidateApplication[0].candidateUserId and candidateApplication[0].applied

As mentioned in the comments above, if there are more instances of that same candidateUserId, only the first will be returned.

Pollux
  • 31
  • 8
  • It still returns/publishes the entire `candidateApplication` array – bp123 Oct 18 '17 at 02:17
  • Doh! From the Meteor doc site: [link](https://docs.meteor.com/api/collections.html#fieldspecifiers), "Field operators such as $ and $elemMatch are not available on the client side yet." – Pollux Oct 18 '17 at 11:34
  • will `candidateUserId` always be as orderly as it seems (1, 2, 3, etc.) or have you simplified it for the example? You may be able to `$slice` out the object you want from the array by its position. – Pollux Oct 18 '17 at 12:43
  • candidateUserId is a random number. I just simplified for the example. – bp123 Oct 18 '17 at 12:46