0

I have a collection called shows, with documents as:

       {
            "url": "http://www.tvmaze.com/shows/167/24",
            "name": "24",
            "genres": [
                "Drama",
                "Action"
            ],
            "runtime": 60
        },
        {
            "url": "http://www.tvmaze.com/shows/4/arrow",
            "name": "Arrow",
            "genres": [
                "Drama",
                "Action",
                "Science-Fiction"
            ],
            "runtime": 60
        }

I wanted to search shows with genre 'Action' and project the result array as

   {
        "url": "http://www.tvmaze.com/shows/167/24",
        "name": "24",
        "genres": [
            "Action" // I want only the matched item in 
         //my result array
        ],
        "runtime": 60
    } , //same for the second doc as well

If I use

db.shows.find({genres:'Action'}, {'genres.$': 1});

It works but the same does not work in aggregate method with $project

Shows.aggregate([
      {
        $match: { 'genres': 'Action'}
      },
      {
        $project: {
          _id: 0,
          url: 1,
          name: 1,
          runtime: 1,
          'genres.$': 1
        }
      }
]);

this is the error I get on this aggregate query

Invalid $project :: caused by :: FieldPath field names may not start with '$'."
Vinita
  • 1,834
  • 2
  • 8
  • 20
  • 1
    The `$` projection will work only on find methods, you can use [$filter](https://docs.mongodb.com/manual/reference/operator/aggregation/filter/) aggregation operator in aggregation query. – turivishal Jun 18 '21 at 07:52
  • Does this answer your question? [How to filter array in a mongodb query](https://stackoverflow.com/questions/30207005/how-to-filter-array-in-a-mongodb-query) – turivishal Jun 18 '21 at 08:00
  • @turivishal, no it did not answer, also what if I am using regex to match the genre 'Action', then how would I do it while projecting, it might not be the exact match. – Vinita Jun 18 '21 at 08:07
  • You can use [$regexMatch](https://docs.mongodb.com/manual/reference/operator/aggregation/regexMatch/) operator inside `$filter`. – turivishal Jun 18 '21 at 08:15
  • @turivishal https://mongoplayground.net/p/tMXtYO2v2y5 , not able to work it out can you help a little – Vinita Jun 18 '21 at 08:26
  • 1
    just remove `/` slashes from both match string. – turivishal Jun 18 '21 at 08:30
  • You can aswer your own question, it will helpful for others as well. – turivishal Jun 18 '21 at 08:53

1 Answers1

0
db.collection.aggregate([
  {
    $match: {
      "genres": {
        $regex: "/^action/",
        $options: "im"
      }
    }
  },
  {
    $project: {
      _id: 0,
      url: 1,
      name: 1,
      runtime: 1,
      genres: {
        $filter: {
          input: "$genres",
          as: "genre",
          cond: {
            $regexMatch: {
              input: "$$genre",
              regex: "/^action/",
              options: "im"
            }
          }
        }
      }
    }
  }
])

Here is how I solved it, Thanks @turivishal for the help

Vinita
  • 1,834
  • 2
  • 8
  • 20