Я новичок в MongoDB и практикую метод агрегирования. Я - мой пример, я хотел бы получить вино, которое было произведено за последние 5 лет (5 лет назад от новейшего вина), затем я хотел бы подсчитать, сколько вин было произведено за этот период времени ( база данных дает нам год вин в целом числе)

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

Благодарность!

0
Jusep 10 Ноя 2020 в 03:48

2 ответа

Лучший ответ

Для преобразования данных вам необходимо использовать различные этапы конвейера агрегации.

структура агрегации MongoDB основана на концепции конвейеров обработки данных. Документы поступают в многоступенчатый конвейер, который преобразует документы в агрегированный результат.

Как вы уже упоминали,

  1. Для начала нужно узнать год выпуска новейшего вина.

Я использовал $ group для группировки данных и $ max используется для получения newestWineYear и целых документов ( $$ ROOT) помещается в data с помощью $ push < / а>

Этап 1

{
    $group: {
      _id: null,
      "newestWineYear": {
        $max: "$year"
      },
      data: {
        $push: "$$ROOT"
      }
    }
}
  1. Выходные данные первого этапа содержат все документы в массиве, который мы назвали data и newestWineYear

Итак, чтобы выровнять массив data $ unwind используется.

Этап 2

 {
    $unwind: "$data"
 }
  1. Подсчитайте количество вин, произведенных за последние 5 лет.

Я использовал $ group для подсчета, и count получается с помощью $ sum.

Этап 3

{
    $group: {
      _id: null,
      count: {
        "$sum": {
          $cond: [
            {
              "$gte": [
                "$data.year",
                {
                  "$subtract": [
                    "$newestWineYear",
                    5
                  ]
                }
              ]
            },
            1,
            0
          ]
        }
      }
    }
}

К $ sum добавляется условие для подсчета только тех вин, которые выпускается последние 5 лет.

Состояние доступно в $ cond.

Он говорит:

 If "data.year" >= [ "$newestWineYear" - 5 ], then add 1 to count, else add 0

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

Окончательный запрос агрегирования можно найти здесь: Playground

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

1
Tiya Jose 10 Ноя 2020 в 14:33

Как вы уже догадались, вам нужно использовать фреймворк агрегации mongo.

Начните с простого конвейера из 3 простых шагов:

  1. group с $ group для получения данных за прошлый год (возвращает массив)
  2. удалить массив и получить отдельные документы (оператор $ unwind)
  3. фильтровать документы с помощью оператора $ match

Наконец, вы можете заменить корень ваших документов, чтобы получить более точные результаты.

Представьте себе такие данные:

[
  {
    "wine": "Red xxx",
    "year": 2018
  },
  {
    "wine": "Red yyy",
    "year": 2017
  },
  {
    "wine": "Red zzz",
    "year": 2017
  },
  {
    "wine": "White 1",
    "year": 2016
  },
  {
    "wine": "White 2",
    "year": 2013
  },
  {
    "wine": "White 3",
    "year": 2017
  },
  {
    "wine": "White 4",
    "year": 2009
  }
]

Вот конвейер и здесь вы можете увидеть результаты на игровой площадке.

db.collection.aggregate({
  $group: {
    _id: null,
    "lastYear": {
      $max: "$year"
    },
    data: {
      $push: "$$ROOT"
    }
  }
},
{
  $unwind: "$data"
},
{
  $match: {
    $expr: {
      $gte: [
        "$data.year",
        {
          "$subtract": [
            "$lastYear",
            5
          ]
        }
      ]
    }
  }
},
{
  "$replaceWith": "$data"
})
0
crivella 10 Ноя 2020 в 17:40