MongoDB: поиск слов, затем подсчет совпадений

#mongodb #mongodb-query #aggregation-framework

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

Вопрос:

У меня есть база данных книг, которая выглядит следующим образом:

 {"_id": ObjectID("1"), "title": "Harry Potter", "year": NumberInt(2000), "author": "JK. Rowling", "genres" : [fantasy, drama]}, 
{"_id": ObjectID("2"), "title": "Harry Potter 99", "year": NumberInt(2020), "author": "JK. Rowling", "genres" : [fantasy, drama]}, 
{"_id": ObjectID("3"), "title": "Book", "year": NumberInt(2020), "author": "Mr. Author", "genres" : [war, romance]}, 
{...}
  

Я хотел бы получить книги, в которых сочетаются жанры «фэнтези» и «драма», преобразовать их названия в заглавные буквы, подсчитать их и, наконец, получить среднее значение года их публикации. Что-то вроде этого:

 {
  "_id" : ["HARRY POTTER", "HARRY POTTER 99],
  "yearavg" : "2010",
  "count" : "2"
}
  

Я не могу пройти группировку, поэтому я написал это до сих пор, хотя это не работает:

 query1 = {"genres" : "Fantasy"}
query2 = {"genres" : "Drama"}
logic = {$and : [query1, query2]}
phase1 = {$match : logic}
phase2 = {$group : {"_id" : "$title", "year" : "$year"}}
phase3 = {$project : {"total" : {"$size" : "$genres"}, "genres" : 1}} 

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

Спасибо!

Ответ №1:

Вы можете попробовать,

  • $match жанры во всем ["fantasy", "drama"] массиве
  • $group по null и создайте массив заголовков после преобразования в верхний регистр, используя $toUpper , получите средний год, используя $avg , получите количество, используя $sum
 db.genres.aggregate([
  { $match: { genres: { $all: ["fantasy", "drama"] } } },
  {
    $group: {
      _id: null,
      titles: { $push: { $toUpper: "$title" } },
      yearavg: { $avg: "$year" },
      count: { $sum: 1 }
    }
  }
])
  

Игровая площадка

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

1. Спасибо! Это работает идеально. Есть какой-нибудь способ, которым я могу сделать средний год целым числом?

2. я могу видеть это в целых числах правильно, если я не ошибаюсь?, для преобразования типов вы можете использовать $toInt operator .