Как установить unevaluatedProperties в MongoDB и чем заменить

Если вы хотите установить unevaluatedProperties в MongoDB, скорее всего, вам нужно не само это поле, а запрет лишних свойств в документе. В MongoDB для такой задачи обычно используют валидатор коллекции $jsonSchema и настройку additionalProperties: false. Если вы работаете через Mongoose, похожую задачу часто решают через strict

Проще говоря: цель не в том, чтобы добавить поле unevaluatedProperties, а в том, чтобы база не принимала документы с неожиданными полями

Вариант для MongoDB: $jsonSchema

Создадим коллекцию products, где разрешены только _id, title, price и inStock

db.createCollection("products", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["title", "price"],
      additionalProperties: false,
      properties: {
        _id: {},
        title: {
          bsonType: "string",
          description: "Название товара обязательно"
        },
        price: {
          bsonType: "number",
          minimum: 0,
          description: "Цена должна быть числом не меньше нуля"
        },
        inStock: {
          bsonType: "bool"
        }
      }
    }
  }
})

Обратите внимание на _id: {}. MongoDB добавляет _id автоматически, поэтому при additionalProperties: false его нужно разрешить, иначе валидатор может мешать нормальной вставке документов

Проверка

Такой документ пройдет:

db.products.insertOne({
  title: "Книга",
  price: 1200,
  inStock: true
})

А такой должен быть отклонен, потому что поле unknownField не описано:

db.products.insertOne({
  title: "Книга",
  price: 1200,
  unknownField: "лишнее поле"
})

Если MongoDB ругается на валидацию, значит ограничение работает

Если коллекция уже существует

Для существующей коллекции используйте collMod:

db.runCommand({
  collMod: "products",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["title", "price"],
      additionalProperties: false,
      properties: {
        _id: {},
        title: { bsonType: "string" },
        price: { bsonType: "number", minimum: 0 },
        inStock: { bsonType: "bool" }
      }
    }
  },
  validationLevel: "strict",
  validationAction: "error"
})

validationAction: "error" означает, что MongoDB будет отклонять неподходящие документы, а не просто писать предупреждение

Вариант для Mongoose

Если данные идут через Node.js и Mongoose, можно запретить лишние поля на уровне схемы:

const productSchema = new mongoose.Schema(
  {
    title: { type: String, required: true },
    price: { type: Number, required: true, min: 0 },
    inStock: { type: Boolean, default: true }
  },
  {
    strict: "throw"
  }
);

При strict: "throw" Mongoose выбросит ошибку, если вы попытаетесь сохранить поле, которого нет в схеме

Что выбрать

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

Если все записи идут только через Mongoose, можно начать со strict: "throw" и схемы Mongoose. Но для важных коллекций надежнее сочетать оба подхода: схема в приложении и валидатор в базе

Частые ошибки

Забыли разрешить _id

При additionalProperties: false обязательно учитывайте _id, потому что MongoDB добавляет его автоматически

Описали price как string

Если цена должна быть числом, используйте bsonType: "number" или более конкретные типы, а не строку

Ждете, что Mongoose защитит базу всегда

Mongoose защищает только тот код, который проходит через Mongoose. Если другой сервис пишет в MongoDB напрямую, правила Mongoose не помогут

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x