当两个模式相互引用时播种mongoose数据

xu3bshqb  于 2023-06-30  发布在  Go
关注(0)|答案(2)|浏览(97)

我试图为我的数据库播种数据,但我的两个模式相互引用,所以我不确定如何可能在另一个之前播种一个。
我想使用fakerjs来处理一些数据,但我有点困惑我该如何处理它。
以下是我的Schemas,它们非常简单,并且都是相互引用的:

import mongoose from "mongoose";
import { loadType } from "mongoose-currency";

const Schema = mongoose.Schema;
loadType(mongoose);

const CategorySchema = new Schema(
  {
    name: String,
    expenses: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Expense",
      },
    ],
  },
  { timestamps: true, toJSON: { getters: true } }
);

const Category = mongoose.model("Category", CategorySchema);

export default Category;

另一个是:

import mongoose from "mongoose";
import { loadType } from "mongoose-currency";

const Schema = mongoose.Schema;
loadType(mongoose);

const ExpenseSchema = new Schema(
  {
    name: String,
    price: {
      type: mongoose.Types.Currency,
      currency: "USD",
      get: (v) => v / 100,
    },
    date: {
      type: Date,
    },
    category: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Category",
    },
  },
  { timestamps: true, toJSON: { getters: true } }
);

const Expense = mongoose.model("Expense", ExpenseSchema);

export default Expense;

有谁知道如果他们互相依赖,我会怎么做?

jv4diomz

jv4diomz1#

参考儿童文档解释了这种情况。
例如(“mongoose”:“^7.3.1”

// @ts-nocheck
import mongoose from 'mongoose';
import util from 'util';
import { config } from '../../config';

const CategorySchema = new mongoose.Schema({
    name: String,
    expenses: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Expense',
        },
    ],
});
const Category = mongoose.model('Category', CategorySchema);

const ExpenseSchema = new mongoose.Schema({
    name: String,
    category: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Category',
    },
});
const Expense = mongoose.model('Expense', ExpenseSchema);

(async function main() {
    mongoose.set('debug', true);
    try {
        await mongoose.connect(config.MONGODB_URI);
        await Promise.all([Category, Expense].map((m) => m.collection.drop()));
        // seed
        const [c1, c2] = [{ name: 'c1' }, { name: 'c2' }].map((v) => new Category(v));
        const [e1, e2, e3] = [
            { name: 'e1', category: c1._id },
            { name: 'e2', category: c1._id },
            { name: 'e3', category: c2._id },
        ].map((v) => new Expense(v));

        c1.expenses.push(e1, e2);
        c2.expenses.push(e3);

        await Promise.all([c1, c2].map((v) => v.save()));
        await Promise.all([e1, e2, e3].map((v) => v.save()));

        // populate
        const c = await Category.findOne({ name: 'c1' }).populate('expenses').exec();
        console.log(c?.toObject());
        const e = await Expense.findOne({ name: 'e1' })
            .populate({ path: 'category', populate: { path: 'expenses' } })
            .exec();
        console.log(util.inspect(e?.toObject(), false, null));
    } catch (error) {
        console.error(error);
    } finally {
        await mongoose.connection.close();
    }
})();

调试日志:

Mongoose: categories.drop()
Mongoose: expenses.drop()
Mongoose: categories.insertOne({ name: 'c1', expenses: [ ObjectId("649d8f7d038538fabd2e1ce3"), ObjectId("649d8f7d038538fabd2e1ce4") ], _id: ObjectId("649d8f7d038538fabd2e1ce1"), __v: 0}, {})
Mongoose: categories.insertOne({ name: 'c2', expenses: [ ObjectId("649d8f7d038538fabd2e1ce5") ], _id: ObjectId("649d8f7d038538fabd2e1ce2"), __v: 0}, {})
Mongoose: expenses.insertOne({ name: 'e1', category: ObjectId("649d8f7d038538fabd2e1ce1"), _id: ObjectId("649d8f7d038538fabd2e1ce3"), __v: 0}, {})
Mongoose: expenses.insertOne({ name: 'e2', category: ObjectId("649d8f7d038538fabd2e1ce1"), _id: ObjectId("649d8f7d038538fabd2e1ce4"), __v: 0}, {})
Mongoose: expenses.insertOne({ name: 'e3', category: ObjectId("649d8f7d038538fabd2e1ce2"), _id: ObjectId("649d8f7d038538fabd2e1ce5"), __v: 0}, {})
Mongoose: categories.findOne({ name: 'c1' }, {})
Mongoose: expenses.find({ _id: { '$in': [ ObjectId("649d8f7d038538fabd2e1ce3"), ObjectId("649d8f7d038538fabd2e1ce4") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined })
{
  _id: new ObjectId("649d8f7d038538fabd2e1ce1"),
  name: 'c1',
  expenses: [
    {
      _id: new ObjectId("649d8f7d038538fabd2e1ce3"),
      name: 'e1',
      category: new ObjectId("649d8f7d038538fabd2e1ce1"),
      __v: 0
    },
    {
      _id: new ObjectId("649d8f7d038538fabd2e1ce4"),
      name: 'e2',
      category: new ObjectId("649d8f7d038538fabd2e1ce1"),
      __v: 0
    }
  ],
  __v: 0
}
Mongoose: expenses.findOne({ name: 'e1' }, {})
Mongoose: categories.find({ _id: { '$in': [ ObjectId("649d8f7d038538fabd2e1ce1") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined })
Mongoose: expenses.find({ _id: { '$in': [ ObjectId("649d8f7d038538fabd2e1ce3"), ObjectId("649d8f7d038538fabd2e1ce4") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined })
{
  _id: new ObjectId("649d8f7d038538fabd2e1ce3"),
  name: 'e1',
  category: {
    _id: new ObjectId("649d8f7d038538fabd2e1ce1"),
    name: 'c1',
    expenses: [
      {
        _id: new ObjectId("649d8f7d038538fabd2e1ce3"),
        name: 'e1',
        category: new ObjectId("649d8f7d038538fabd2e1ce1"),
        __v: 0
      },
      {
        _id: new ObjectId("649d8f7d038538fabd2e1ce4"),
        name: 'e2',
        category: new ObjectId("649d8f7d038538fabd2e1ce1"),
        __v: 0
      }
    ],
    __v: 0
  },
  __v: 0
}
qxsslcnc

qxsslcnc2#

这是我在感谢上面的答案降落:

(async function main() {
  await Promise.all([Category, Expense].map((m) => m.collection.drop()));
  const newCategories = categories.map((v) => new Category(v));

  const _ids = newCategories.map((item) => item._id);

  const expenses = Array.from({ length: 100 }, () => ({
    description: faker.lorem.sentence({ min: 3, max: 5 }),
    price: faker.finance.amount({ min: 5, max: 50, dec: 2, symbol: "$" }),
    date: faker.date.past({ years: 1 }),
    category: faker.helpers.arrayElement(_ids),
  })).map((v) => new Expense(v));

  newCategories.forEach((category) =>
    expenses.map((expense) => {
      if (expense.category === category._id) {
        category.expenses.push(expense._id);
      }
    })
  );

  await Promise.all(expenses.map((expense) => expense.save()));
  await Promise.all(newCategories.map((category) => category.save()));
})();

不确定这是否是最有效的,如果有人知道更好的方法,请lmk!

相关问题