繁体   English   中英

MongoDB、Mongoose:如何在另一个文档的数组中引用一个文档?

[英]MongoDB, Mongoose: How to refer to a document inside an array of another document?

我使用 MongoDB 才一个多月,而且我对关系数据库也没有太多经验。 我会尝试在下面解释我想做什么。

我在 mongoose 中有一个这样的架构:

import mongoose, { model, Schema } from "mongoose";
import { IBudget } from "../types/budget";
import User from "./user.model";

const budgetSchema = new Schema<IBudget>({
  user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: User },
  categories: {
    type: [
      {
        title: { type: "string", required: true, trim: true },
        amount: { type: "number", required: true, default: 0 },
        color: { type: "string", required: true },
        managed: { type: "boolean", required: true, default: true },
        editable: { type: "boolean", required: true, default: true },
        description: { type: "string", maxlength: 120 },
      },
    ],
    required: true,
    maxlength: [12, "Cannot have more than 12 categories"],
    minlength: [1, "Need at least 1 cateogry"],
  },
  month: {
    type: Number,
    required: [true, "Please add month"],
    min: 1,
    max: 12,
  },
  year: { type: Number, required: [true, "Please add the year"] },
});

const Budget = model("Budget", budgetSchema);

export default Budget;

这样,当我使用Budget.create({...budgetObject})创建预算文档时,我在数据库中创建了以下文档。 在此处输入图像描述

我有另一个名为Expense的模式,如下所示:

import mongoose, { model, Schema } from "mongoose";
import { IExpense } from "../types/expense";
import User from "./user.model";

const expenseSchema = new Schema<IExpense>(
  {
    title: { type: String, required: true, trim: true, maxlength: 40 },
    description: { type: String, trim: true, maxlength: 260 },
    expenseDate: { type: Date, default: Date.now },
    category: {
      type: String,
      required: [true, "Please add the category name"],
    },
    user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: User },
    amount: { type: Number, required: true },
    reverted: { type: Boolean, required: true, default: false },
  },
  { timestamps: false }
);

const Expense = model("Expense", expenseSchema);
export default Expense;

我的问题是:如何将支出文件的类别引用到预算文件中类别数组中的项目之一?

如您所见{ type: mongoose.Schema.Types.ObjectId, required: true, ref: User },来引用其他文档。 但我不明白这对嵌套在另一个文档中的子文档或数组字段内的文档有何作用。

我什至不确定这是否可行,在这种情况下,将高度赞赏针对相同行为的替代方法。

看起来你在一个月内学到了很多东西:-)。

对于您的用例,而不是在budgetSchema中对category字段进行硬编码,您应该首先创建一个categorySchema ,例如:

import { model, Schema } from "mongoose";
import { ICategory } from "../types/category";

const categorySchema =
  new Schema() <
  ICategory >
  {
    title: { type: "string", required: true, trim: true },
    amount: { type: "number", required: true, default: 0 },
    color: { type: "string", required: true },
    managed: { type: "boolean", required: true, default: true },
    editable: { type: "boolean", required: true, default: true },
    description: { type: "string", maxlength: 120 },
  };

const Category = model("Category", categorySchema);

export default Category;

然后在您的 budgetSchema 中,您的类别字段将是一个categorySchema object id 数组,如下所示:

import mongoose, { model, Schema } from "mongoose";
import { IBudget } from "../types/budget";
import User from "./user.model";
import Category from "./category.model";

const budgetSchema =
  new Schema() <
  IBudget >
  {
    user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: User },
    categories: [
      { type: mongoose.Schema.Types.ObjectId, required: true, ref: Category },
    ],
    month: {
      type: Number,
      required: [true, "Please add month"],
      min: 1,
      max: 12,
    },
    year: { type: Number, required: [true, "Please add the year"] },
  };

const Budget = model("Budget", budgetSchema);

export default Budget;

由于类别现在是单独模式的文档,您现在可以像这样在 expenseSchema 中引用它们:

import mongoose, { model, Schema } from "mongoose";
import { IExpense } from "../types/expense";
import User from "./user.model";
import Category from "./category.model";

const expenseSchema =
  new Schema() <
  IExpense >
  ({
    title: { type: String, required: true, trim: true, maxlength: 40 },
    description: { type: String, trim: true, maxlength: 260 },
    expenseDate: { type: Date, default: Date.now },
    category: {
      type: mongoose.Schema.Types.ObjectId,
      required: [true, "Please add the category name"],
      ref: Category,
    },
    user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: User },
    amount: { type: Number, required: true },
    reverted: { type: Boolean, required: true, default: false },
  },
  { timestamps: false });

const Expense = model("Expense", expenseSchema);
export default Expense;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM