我有好几种产品,例如手机、笔记本电脑、耳机等。所有这些产品最终结果都是你一个概括的
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
更改计数字段来实现此目的。但它就是不起作用并且不会抛出任何错误。
它不起作用,因为基本模式无法访问继承模式中的键。 在本例的以下语句中,基本模式尝试访问继承模式中的键计数。 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
}