Mongoose, правильный способ обновления документов с глубокими вложенными схемами - PullRequest
0 голосов
/ 07 июня 2018

Хотелось бы узнать, какой самый эффективный способ обновить документ, в котором также есть вложенная схема.Обычно я просто использую Model.findByIdAndUpdate(id, updatedValues) ..., однако, если я пытаюсь сделать это с документом, имеющим глубоко вложенную схему, я получаю эту ошибку: CastError: Cast to Embedded failed for value "{ _id: 5b1936aab50e727c83687797, en_US: 'Meat', lt_LT: 'Mesa' }" at path "title".

Мои схемы выглядят примерно так:

const titleSchema = new Schema({
    en_US: {
        type: String,
        required: true
    },
    lt_LT: {
        type: String,
        default: null
    }
})

const categorySchema = new Schema({
    title: titleSchema
});

const ingredientSchema = new Schema({
    title: {
        type: titleSchema,
        required: true
    },
    category: categorySchema,
    calories: {
        type: Number,
        min: 0,
        default: 0
    },
    vitamins: [String]
})

И я пытаюсь обновить следующим образом:

{
    title: {
        en_US: 'Pork',
        lt_LT: 'Kiauliena'
    },
    category: {
        _id: '5b193a230af63a7e80b6acd8',
        title: {
            _id: '5b193a230af63a7e80b6acd7'
            en_US: 'Meat',
            lt_LT: 'Mesa'
        }
    }
}

Обратите внимание, я получаю новый объект категории из отдельной коллекции, используя только категорию _id, но конечный объект обновления, который входит вФункция findByIdAndUpdate() похожа на приведенную выше.

Единственная найденная мной тренировка - удалить категорию из обновленных значений, обновить документ с помощью findByIdAndUpdate(), получить обновленный документ, назначить ему новую категориюи сохрани это.

Работает просто отлично и все, но для этого требуется два вызова базы данных, возможно ли сделать это всего за один?

1 Ответ

0 голосов
/ 08 июня 2018

Попробуйте обновить схему следующим образом:

const titleSchema = new Schema({
    en_US: {
        type: String,
        required: true
    },
    lt_LT: {
        type: String,
        default: null
    }
});

const ingredientSchema = new Schema({
    title: {
        type: titleSchema,
        required: true
    },
    category: {
        title: titleSchema
    },
    calories: {
        type: Number,
        min: 0,
        default: 0
    },
    vitamins: [String]
});
...