MongoDB: группировка и подсчет элементов

#mongodb #mongodb-query #aggregation-framework

#mongodb #mongodb-запрос #агрегация-фреймворк

Вопрос:

У меня есть список книг. Я хотел бы получить количество жанров, которые написали авторы, также я хотел бы добавить к результатам, которые относятся к этим жанрам. Моя база данных выглядит следующим образом:

 {"_id": ObjectID("1), "title": "Harry Potter", "year": NumberInt(2000), "author": "JK. Rowling", 
"genres": "Fantasy"}, 
"_id": ObjectID("2"), "title": "Harry Potter 99", "year": NumberInt(2020), "author": "JK. Rowling", 
"genres": "Drama"}, "_id": ObjectID("2"), "title": "Harry Potter", "year": NumberInt(2000), "author": "JK. Rowling", 
"genres": "Drama"}, {...}
  

Итак, мой код пока выглядит так:

 phase1 = {$group : {"_id" : "$author"}, "countgenres" : {$sum : 1}}
phase2 = {$addFields : "genres"}}
phase3 = {$sort : {"numgenres" : -1}}

steps = [phase1, phase2, phase3]
db.database.aggregate(steps)
  

Это не работает для меня, поэтому я хотел бы, чтобы кто-нибудь помог мне написать правильный код для этого. Результат должен выглядеть следующим образом:

 {

"_id" : "JK. Rowling",

"countgenres" : 4,

"genres" : [
"Fantasy",
"Drama"

]
}
  

Я опубликовал аналогичный вопрос час назад, но я допустил ошибку в базе данных, спасибо за ваше время.

Комментарии:

1. Привет, в примере ввода вывод должен иметь только 2 жанра, верно?

2. Извините, моя ошибка, исправлено!

3. Я тоже обновил свой ответ.

Ответ №1:

Попробуйте этот запрос, в котором я добавил нового автора, чтобы также проверить сортировку.

 db.collection.aggregate([
  {
    "$match": {
      "author": "JK. Rowling"
    }
  },
  {
    "$unwind": "$genres"
  },
  {
    "$group": {
      "_id": "$author",
      "genres": {
        "$addToSet": "$genres"
      }
    }
  },
  {
    "$project": {
      "numgenres": {
        "$size": "$genres"
      },
      "genres": 1
    }
  },
  {
    "$sort": {
      "numgenres": -1
    }
  }
])
  

Запрос сначала $unwind отделяет значения от genres и использует $addToSet , чтобы избежать повторения значений. Затем используйте $project для получения размера массива.

Комментарии:

1. Спасибо! Но при этом я собираю много авторов вместе, я хотел бы получать по одному автору за раз.

2. Обновленный ответ. Надеюсь, это поможет.

3. Кроме того, если вам нужен только один автор, зачем вы пытаетесь сортировать по numgenres ? Всегда будет только один результат документа, верно?

4. Да, я бы хотел, чтобы у каждого автора вы могли видеть количество жанров, которые они написали. Как я мог отсортировать его по «numgenres»?

5. Но, если вы хотите выполнить поиск только от одного автора, вы получите только один документ с номером numgenres для конкретного автора. Это верно? Итак, если есть только один результат, что вы хотите заказать?