Skip to main content

deno_mongo_schema

Extend from deno_mongo v0.29.4, support Schema and extend some API.

ci tag

Breaking changes when on v0.9.0, because I want to change the word SchemaDecorator to Schema, and the word Schema changed to BaseSchema.

If you are using the old version, then you can global replace by IDE or run

deno run --allow-read --allow-write --unstable https://deno.land/x/deno_mongo_schema@v0.10.0/build/update.ts

once in your project.

hooks

import {
  BaseSchema,
  getDB,
  getModel,
  MongoFactory,
  MongoHookMethod,
  Prop,
  Schema,
  UpdateExOptions,
} from "https://deno.land/x/deno_mongo_schema@v0.10.0/mod.ts";
import type { Document } from "https://deno.land/x/deno_mongo_schema@v0.10.0/mod.ts";

await MongoFactory.forRoot("mongodb://localhost:27017/test");

@Schema()
class User extends BaseSchema {
  @Prop()
  age!: number;

  @Prop({
    required: true,
  })
  name!: string;

  @Prop({
    default: Date.now,
    expires: 60, // seconds
  })
  expires?: Date;
}

const UserSchema = SchemaFactory.createForClass(User);

UserSchema.pre(
  MongoHookMethod.update,
  function (filter: Document, doc: Document, options?: UpdateExOptions) {
    console.log("----pre----", filter, doc, options);
    if (!doc.$set) {
      doc.$set = {};
    }
    doc.$set.modifyTime = new Date();
  },
);

UserSchema.post(MongoHookMethod.findOneAndUpdate, function (doc) {
  console.log("----post----", doc);
  doc.name = "haha";
});

const userModel = await MongoFactory.getModel(User);

const id = await userModel.insertOne({
  "name": "zhangsan",
  "age": 18,
});

UserSchema.post(MongoHookMethod.findOne, function (doc) {
  console.log("----post---findOne----", doc);
});

// console.log(id);
const info = await userModel.findById(id, {
  projection: {
    name: 1,
  },
});
console.log(info);

UserSchema.post(MongoHookMethod.findMany, function (doc) {
  console.log("----post---findMany----", doc);
});

const arr = await userModel.findMany({});
console.log(arr);

UserSchema.post(MongoHookMethod.delete, function (doc) {
  console.log("----post---delete----", doc);
});

const del = await userModel.deleteOne({
  name: "zhangsan",
});
console.log(del);

const delMulti = await userModel.deleteMany({
  name: "zhangsan",
});
console.log(delMulti);

Here are some useful APIs:

  • find
    • findById
    • findOne
    • findMany
    • countDocuments
    • aggregate
    • distinct
  • insert
    • insertOne
    • insertMany
  • update
    • findByIdAndUpdate
    • findOneAndUpdate
    • updateMany
    • updateOne
  • delete
    • deleteMany
    • deleteOne/findOneAndDelete
    • deleteById/findByIdAndDelete
  • index
    • syncIndexes
    • dropIndexes
    • listIndexes
    • createIndexes
  • drop collection
    • drop

Virtual

Or you can use virtual like this:

import {
  BaseSchema,
  MongoFactory,
  Prop,
  Schema,
} from "https://deno.land/x/deno_mongo_schema@v0.10.0/mod.ts";

await MongoFactory.forRoot("mongodb://localhost:27017/test");

@Schema()
class User extends BaseSchema {
  @Prop()
  group!: string;

  @Prop()
  title!: string;
}

@Schema()
class Role extends BaseSchema {
  @Prop()
  userId!: string;

  @Prop()
  name!: string;
}

const RoleSchema = SchemaFactory.createForClass(Role);

RoleSchema.virtual("user", {
  ref: User,
  localField: "userId",
  foreignField: "_id",
  justOne: true,
  isTransformLocalFieldToObjectID: true,
});

// Role.populate("user", {
//   // _id: 0,
//   group: 1,
//   // title: 1,
// });
// Role.populate("user", "group");
// Role.populate("user", "-group -createTime");
// Role.populate("user", "title group");

const roleModel = await MongoFactory.getModel(Role);

// roleModel.insertOne({
//   userId: id,
//   name: "normal",
// });

console.log(
  await roleModel.findMany({}, {
    projection: {
      name: 1,
      userId: 1,
    },
    // skip: 1,
    // limit: 1,
    populates: {
      // user: {
      //   // _id: 0,
      //   group: 1,
      //   title: 1,
      // },
      // user: "group",
      user: true,
      // user: "-_id -title",
    },
  }),
);

Special collection name

If you donnot want to use the default collection name, you must regiter it by yourself.

SchemaFactory.createForClass(Role, "mongo_test_schema_roles");

Then if you still want to use virtual, you must use your registered name instead of Schema Class.

UserSchema.virtual("role", {
  ref: "mongo_test_schema_roles",
  localField: "roleId",
  foreignField: "_id",
  justOne: true,
  // isTransformLocalFieldToObjectID: true,
  // isTransformObjectIDToLocalField: true
});

TODO

  • Modify schema as a decorator
  • Unit
  • Configurable whether to convert _id
  • Configurable the createTime and modifyTime