Преобразование данных MongoDB

MongoDBMongoDBBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (lab) вы научитесь преобразовывать данные MongoDB с помощью базовых операций агрегации. В рамках занятия рассматриваются пять ключевых этапов: выбор полей вывода, переименование полей, вычисление новых полей, форматирование вывода и фильтрация результатов. На этих этапах вы получите практический опыт в изменении структуры и анализе данных, хранящихся в коллекциях MongoDB. В практическом занятии предоставляется примерный набор данных о книгах и показано, как использовать конвейер агрегации (aggregation pipeline) для извлечения, обработки и представления данных более осмысленным образом.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ArrayandEmbeddedDocumentsGroup(["Array and Embedded Documents"]) mongodb(("MongoDB")) -.-> mongodb/AggregationOperationsGroup(["Aggregation Operations"]) mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/QueryOperationsGroup -.-> mongodb/query_with_conditions("Query with Conditions") mongodb/QueryOperationsGroup -.-> mongodb/project_fields("Project Fields") mongodb/DataTypesGroup -.-> mongodb/use_numeric_data_types("Use Numeric Data Types") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/query_embedded_documents("Query Embedded Documents") mongodb/AggregationOperationsGroup -.-> mongodb/aggregate_group_totals("Aggregate Group Totals") subgraph Lab Skills mongodb/insert_document -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/query_with_conditions -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/project_fields -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/use_numeric_data_types -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/work_with_array_data_types -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/query_embedded_documents -.-> lab-422094{{"Преобразование данных MongoDB"}} mongodb/aggregate_group_totals -.-> lab-422094{{"Преобразование данных MongoDB"}} end

Выбор полей вывода

На этом этапе мы научимся использовать конвейер агрегации (aggregation pipeline) MongoDB для выбора и преобразования полей вывода. Агрегация - это мощный способ обработки и анализа данных в MongoDB.

Сначала запустим оболочку MongoDB (MongoDB shell):

mongosh

Теперь создадим примерную коллекцию книг для работы:

use bookstore

db.books.insertMany([
    {
        title: "MongoDB Basics",
        author: "Jane Smith",
        price: 29.99,
        pages: 250,
        categories: ["Database", "Programming"]
    },
    {
        title: "Python Deep Dive",
        author: "John Doe",
        price: 39.99,
        pages: 450,
        categories: ["Programming", "Python"]
    },
    {
        title: "Data Science Handbook",
        author: "Alice Johnson",
        price: 49.99,
        pages: 600,
        categories: ["Data Science", "Programming"]
    }
])

Теперь используем конвейер агрегации для выбора конкретных полей вывода:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      bookTitle: "$title",
      bookAuthor: "$author"
    }
  }
]);

Пример вывода:

[
  { bookTitle: 'MongoDB Basics', bookAuthor: 'Jane Smith' },
  { bookTitle: 'Python Deep Dive', bookAuthor: 'John Doe' },
  { bookTitle: 'Data Science Handbook', bookAuthor: 'Alice Johnson' }
]

Разберём, что мы сделали:

  • $project - это этап агрегации, который изменяет структуру документов
  • _id: 0 исключает стандартный идентификатор документа MongoDB
  • bookTitle: "$title" переименовывает поле 'title' в 'bookTitle'
  • bookAuthor: "$author" переименовывает поле 'author' в 'bookAuthor'

Знак $ перед именами полей сообщает MongoDB использовать значение этого поля.

Переименование полей

На этом этапе мы рассмотрим более продвинутые техники переименования полей с использованием конвейера агрегации (aggregation pipeline) MongoDB. Мы будем использовать коллекцию книг, которую создали на предыдущем этапе.

Продолжим работу в оболочке MongoDB (MongoDB shell):

mongosh

Сначала переключимся на нашу базу данных "bookstore":

use bookstore

Теперь используем более сложный этап $project для переименования и преобразования нескольких полей:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      bookInfo: {
        name: "$title",
        writer: "$author",
        bookLength: "$pages",
        pricing: "$price"
      },
      genres: "$categories"
    }
  }
]);

Пример вывода:

[
  {
    bookInfo: {
      name: 'MongoDB Basics',
      writer: 'Jane Smith',
      bookLength: 250,
      pricing: 29.99
    },
    genres: [ 'Database', 'Programming' ]
  },
  //... other book documents
]

Разберём технику переименования:

  • Мы создали вложенный объект bookInfo с переименованными полями
  • name заменяет title
  • writer заменяет author
  • bookLength заменяет pages
  • pricing заменяет price
  • Мы также сохранили categories как genres

Вы также можете использовать этап $rename для более простого переименования полей:

db.books.aggregate([
  {
    $rename: {
      title: "bookName",
      author: "bookWriter"
    }
  }
]);

Этот этап напрямую переименовывает поля в исходных документах.

Вычисление новых полей

На этом этапе мы научимся создавать новые поля, выполняя вычисления с использованием конвейера агрегации (aggregation pipeline) MongoDB. Продолжим работу с нашей базой данных "bookstore".

Начнем с запуска оболочки MongoDB (MongoDB shell):

mongosh

Переключимся на базу данных "bookstore":

use bookstore

Мы будем использовать этап $addFields для создания новых вычисляемых полей:

db.books.aggregate([
  {
    $addFields: {
      totalValue: { $multiply: ["$price", 1.1] },
      discountedPrice: { $multiply: ["$price", 0.9] },
      pageCategories: {
        $concat: [
          { $toString: "$pages" },
          " page ",
          { $arrayElemAt: ["$categories", 0] }
        ]
      }
    }
  }
]);

Пример вывода:

[
  {
    _id: ObjectId("..."),
    title: "MongoDB Basics",
    author: "Jane Smith",
    price: 29.99,
    pages: 250,
    categories: ["Database", "Programming"],
    totalValue: 32.989,
    discountedPrice: 26.991,
    pageCategories: "250 page Database"
  },
  //... other book documents
]

Разберём выполненные вычисления:

  • totalValue: Умножает цену на 1.1 (наценка 10%)
  • discountedPrice: Умножает цену на 0.9 (скидка 10%)
  • pageCategories: Объединяет количество страниц с первой категорией с использованием $concat

Мы также можем выполнять более сложные вычисления. Вычислим рейтинг книги на основе количества страниц:

db.books.aggregate([
  {
    $addFields: {
      bookRating: {
        $switch: {
          branches: [
            { case: { $lt: ["$pages", 300] }, then: "Short Book" },
            { case: { $lt: ["$pages", 500] }, then: "Medium Book" }
          ],
          default: "Long Book"
        }
      }
    }
  }
]);

В этом примере используется $switch для классификации книг по количеству страниц.

Форматирование вывода

На этом этапе мы рассмотрим различные техники форматирования и преобразования вывода с использованием конвейера агрегации (aggregation pipeline) MongoDB. Продолжим работу с нашей базой данных "bookstore".

Начнем с запуска оболочки MongoDB (MongoDB shell):

mongosh

Переключимся на базу данных "bookstore":

use bookstore

Сначала используем $toUpper и $toLower для форматирования текстовых полей:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      titleUpperCase: { $toUpper: "$title" },
      authorLowerCase: { $toLower: "$author" }
    }
  }
]);

Пример вывода:

[
  {
    titleUpperCase: 'MONGODB BASICS',
    authorLowerCase: 'jane smith'
  },
  //... other book documents
]

Далее отформатируем числовые значения с использованием $round и создадим отформатированные строки цен:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      roundedPrice: { $round: ["$price", 1] },
      formattedPrice: {
        $concat: ["$", { $toString: { $round: ["$price", 2] } }]
      }
    }
  }
]);

Пример вывода:

[
  {
    title: 'MongoDB Basics',
    roundedPrice: 30,
    formattedPrice: '$29.99'
  },
  //... other book documents
]

Мы также можем форматировать массивы и создавать сложные строковые представления:

db.books.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      categoriesSummary: {
        $reduce: {
          input: "$categories",
          initialValue: "",
          in: {
            $concat: [
              "$$value",
              { $cond: [{ $eq: ["$$value", ""] }, "", ", "] },
              "$$this"
            ]
          }
        }
      }
    }
  }
]);

Пример вывода:

[
  {
    title: 'MongoDB Basics',
    categoriesSummary: 'Database, Programming'
  },
  //... other book documents
]

В последнем примере используется $reduce для объединения элементов массива в строку, разделенную запятыми.

Фильтрация результатов

На этом последнем этапе мы рассмотрим различные техники фильтрации с использованием конвейера агрегации (aggregation pipeline) MongoDB. Продолжим работу с нашей базой данных "bookstore", чтобы продемонстрировать разные способы фильтрации результатов.

Начнем с запуска оболочки MongoDB (MongoDB shell):

mongosh

Переключимся на базу данных "bookstore":

use bookstore

Сначала отфильтруем книги с использованием простых операторов сравнения:

db.books.aggregate([
  {
    $match: {
      price: { $gt: 30 },
      pages: { $lt: 500 }
    }
  }
]);

Этот запрос фильтрует книги, которые:

  • Имеют цену больше 30
  • Имеют меньше 500 страниц

Пример вывода:

[
  {
    _id: ObjectId("..."),
    title: "Python Deep Dive",
    author: "John Doe",
    price: 39.99,
    pages: 450,
    categories: ["Programming", "Python"]
  }
]

Далее используем более сложную фильтрацию с операциями над массивами:

db.books.aggregate([
  {
    $match: {
      categories: { $in: ["Programming"] }
    }
  }
]);

Этот запрос находит все книги, в категориях которых есть "Programming".

Мы также можем комбинировать несколько техник фильтрации:

db.books.aggregate([
  {
    $match: {
      $or: [{ pages: { $gt: 400 } }, { categories: { $in: ["Database"] } }]
    }
  },
  {
    $project: {
      title: 1,
      pages: 1,
      categories: 1
    }
  }
]);

Этот более сложный запрос:

  • Находит книги с более чем 400 страницами ИЛИ в категории "Database"
  • Выводит только определенные поля

Пример вывода:

[
  {
    _id: ObjectId("..."),
    title: "Data Science Handbook",
    pages: 600,
    categories: ["Data Science", "Programming"]
  },
  {
    _id: ObjectId("..."),
    title: "MongoDB Basics",
    pages: 250,
    categories: ["Database", "Programming"]
  }
]

Резюме

В этом практическом занятии (lab) вы научились использовать конвейер агрегации (aggregation pipeline) MongoDB для выбора и преобразования полей вывода. Вы начали с создания примерной коллекции книг, затем использовали этап $project для выбора определенных полей и их переименования. Вы также рассмотрели более продвинутые техники переименования полей, включая использование вычисляемых выражений и вложенных полей. Наконец, вы научились вычислять новые поля, форматировать вывод и фильтровать результаты. Эти навыки являются важными для эффективной обработки и анализа данных в MongoDB.