Home > Mobile >  MongoDB Aggregate keep results
MongoDB Aggregate keep results

Time:12-06

Is there a way to keep results from a match under a new field, and under another new field some computed value?

I'm trying to extract a set of genres from a collection of movies, and also keep original results...

Document example:

{
  "_id": "62e97ba6ec445b864fc3bc39",
  "id": 19913,
  "genres": [
    "Comedy",
    "Drama",
    "Romance"
  ],
  "imdb_id": "tt1022603",
  "overview": "Tom, greeting-card writer and hopeless romantic...",
  "title": "(500) Days of Summer",
  "release_date": "2009-07-17",
}

Desired output:

{
  result: [
    ... movies
  ]
  categories: [
    "Comedy",
    "Drama",
    "Romance"
  ]
}

What I have so far:

use('the_base');

function matchGenre(genre) {
  return {
    "$match": {
      "genres": genre,
    }
  };
}

function limit(num) {
  return {
    "$limit": num
  };
}

db.movie.aggregate([
  matchGenre("Drama"),
  limit(5),
  {"$unwind": "$genres"},
  {"$group": {
    "_id": 0,
    "gens": { "$addToSet": "$genres" }      
  }}
]);

My current result:

{
    "_id": 0,
    "gens": [
      "Romance",
      "Comedy",
      "Thriller",
      "Science Fiction",
      "Fantasy",
      "Drama",
      "Crime",
      "Action",
      "Mystery",
      "Adventure",
      "Horror"
    ]
  }

CodePudding user response:

I would generally use facets.

Here's an example: https://mongoplayground.net/p/PbORyp4JaF5

db.collection.aggregate([
  {
    $facet: {
      results: [
        {
          $match: {}
        }
      ],
      categories: [
        {
          $unwind: "$genres"
        },
        {
          $sortByCount: "$genres"
        }
      ],
      release_date: [
        {
          $unwind: "$release_date"
        },
        {
          $sortByCount: "$release_date"
        }
      ]
    }
  }
])

I have taken the liberty to add an additional facet of release_date, and also ensure that there is a count present in each of the facets, as this is often helpful and required.

  • Related