mongoose findAndUpdate 与判别器

问题描述 投票:0回答:1

我有好几种产品,例如手机、笔记本电脑、耳机等。所有这些产品最终结果都是你一个概括的

ProductsModel

产品型号

import { Schema, model } from 'mongoose'

export const productsDiscriminatorKey = 'productKind'

const ProductsSchema = new Schema(
    {
        name: { type: String },
    },
    { productsDiscriminatorKey, timestamps: true }
)

export default model('Products', ProductsSchema)

手机型号

import mongoose, { Schema } from 'mongoose'

import ProductsModel, { productsDiscriminatorKey } from './ProductsModel.js'

const PhoneSchema = new Schema(
    {
        name: { type: String, required: true },
        price: { type: String, required: true },
        color: { type: String, required: true },
        memory: { type: String, required: true },
        screen: { type: String, required: true },
        fps: { type: String, required: true },
        sim: { type: String, required: true },
        preview: { type: String, required: true },
        images: [{ type: String, required: true }],
        category: {
            type: mongoose.Schema.ObjectId,
            ref: 'Category',
        },
        type: {
            type: mongoose.Schema.ObjectId,
            ref: 'Type',
        },
        count: { type: Number },
    },
    { productsDiscriminatorKey }
)

const PhoneModel = ProductsModel.discriminator('Phones', PhoneSchema)
export default PhoneModel

我实现了按数量从数据库中删除产品的逻辑,而不是一次性删除整个模型。如果我专门在

PhoneModel
或其他模型中使用它(不在
ProductsModel
中),那么所有逻辑都可以正常工作。但一旦我尝试从
ProductsModel
执行此操作,它就不会更改
count
字段。

删除逻辑

    async delete(req, res) {
        try {
            const { id } = req.params
            const { count } = req.body

            const candidate = await ProductsModel.findById(id)

            if (candidate.count < count) {
                return res.status(500).json({ message: 'More than count in base' })
            }

            if (candidate.count === count || !count) {
                await ProductsModel.findByIdAndDelete(id)
                return res.status(200).json({ message: 'All deleted' })
            }

            if (candidate.count > count) {
                await ProductsModel.findByIdAndUpdate({ _id: id }, { count: candidate.count - count })

                return res.status(200).json({ message: `${count} successfully deleted` })
            }
        } catch (error) {
            return res.status(500).json({ message: 'Server error' })
        }
    }

也就是说,有时您需要删除的不是一次性全部,而是一定数量的(

count
)。我通过简单地使用
findByIdAndUpdate
更改计数字段来实现此目的。但它就是不起作用并且不会抛出任何错误。

javascript mongodb express mongoose
1个回答
0
投票

它不起作用,因为基本模式无法访问继承模式中的键。 在本例的以下语句中,基本模式尝试访问继承模式中的键计数。 ProductsModel 和 PhoneModel 分别是基础模式和继承模式。键计数属于继承的架构 PhoneModel。它不属于基本架构 ProductsModel。因此 mongoose 将忽略这个更新文档 { count: Candidate.count - count }.

await ProductsModel.findByIdAndUpdate({ _id: id }, { count: candidate.count - count })

但是,由于两个模式中都存在键 _id,因此以下查询将正常工作。

const candidate = await ProductsModel.findById(id)
await ProductsModel.findByIdAndDelete(id)

以下代码演示了相同的内容。请注意这些行 - 第 1 行、第 2 行和第 3 行。在所有这些行中,给定的断言都会通过,因为基本模式无法访问继承模式中的键。

const mongoose = require('mongoose');
const { Schema } = mongoose;
const asserts = require('assert');

const options = { discriminatorKey: 'kind' };

const parentSchema = new Schema({ parentkey1: String }, options);
const Parent = mongoose.model('Parent', parentSchema);

const childSchema = new Schema({ childkey1: String }, options);
const Child = Parent.discriminator('Child', childSchema, options);

let parentdoc = new Parent({
  parentkey1: 'parentkey1',
});

let childdoc = new Child({
  parentkey1: 'parentkey1',
  childkey1: 'childkey1',
});

// document objects
asserts.ok(parentdoc._id);
asserts.ok(childdoc._id);

asserts.ok(parentdoc.parentkey1);
asserts.ok(!parentdoc.childkey1);  // line 1
asserts.ok(childdoc.parentkey1);
asserts.ok(childdoc.childkey1);

run().catch((err) => console.log(err));
async function run() {
  await mongoose.connect('mongodb://127.0.0.1:27017/test');
  await Parent.deleteMany();
  await Child.deleteMany();
  await parentdoc.save();
  await childdoc.save();

  parentdoc = await Parent.findById(parentdoc._id);
  childdoc = await Child.findById(childdoc._id);

  asserts.ok(parentdoc._id);
  asserts.ok(childdoc._id);

  asserts.ok(parentdoc.parentkey1);
  asserts.ok(!parentdoc.childkey1); // line 2
  asserts.ok(childdoc.parentkey1);
  asserts.ok(childdoc.childkey1);

  parentdoc = await Parent.findByIdAndUpdate(parentdoc._id, {
    childkey1: 'new value',
  });
  asserts.ok(parentdoc.parentkey1);
  asserts.ok(!parentdoc.childkey1);  // line 3
}
© www.soinside.com 2019 - 2024. All rights reserved.