引用字段上的猫鼬打字稿查找方法

时间:2020-08-30 15:23:42

标签: node.js mongodb typescript mongoose

我正在尝试查找属于特定组织的所有用户。为此,我有两个模型:

组织

import mongoose from 'mongoose';
import { updateIfCurrentPlugin } from 'mongoose-update-if-current';

/**
 * An interface that describes the properties
 * that are required to create a new Organization
 */
interface OrganizationAttrs {
  id: string;
  name: string;
}

/**
 * An interface that describes the properties
 * that a Organization model has
 */
interface OrganizationModel extends mongoose.Model<OrganizationDoc> {
  build(attrs: OrganizationAttrs): OrganizationDoc;
}

/**
 * An interface that describes the properties
 * that a Organization Document has
 */
export interface OrganizationDoc extends mongoose.Document {
  name: string;
  version: number;
}

const organizationSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: true,
      unique: true,
      trim: true,
    },
  },
  {
    toJSON: {
      transform(_doc, ret) {
        ret.id = ret._id;
        delete ret._id;
      },
    },
  }
);

organizationSchema.set('versionKey', 'version');
organizationSchema.plugin(updateIfCurrentPlugin);

organizationSchema.statics.findByEvent = (event: {
  id: string;
  version: number;
}) => {
  return Organization.findOne({
    _id: event.id,
    version: event.version - 1,
  });
};

organizationSchema.statics.build = (attrs: OrganizationAttrs) => {
  return new Organization({
    _id: attrs.id,
    name: attrs.name,
  });
};

const Organization = mongoose.model<OrganizationDoc, OrganizationModel>(
  'Organization',
  organizationSchema
);

export { Organization };

和用户


import mongoose from 'mongoose';
import { Password } from '../services/password-service';
import { RoleDoc } from './role';
import { OrganizationDoc } from './organization';

/**
 * An interface that describes the properties
 * that are required to create a new User
 */
interface UserAttrs {
  email: string;
  firstName: string;
  lastName: string;
  password: string;
  organization: OrganizationDoc;
}

/**
 * An interface that describes the properties
 * that a User model has
 */
interface UserModel extends mongoose.Model<UserDoc> {
  build(attrs: UserAttrs): UserDoc;
}

/**
 * An interface that describes the properties
 * that a User Document has
 */
interface UserDoc extends mongoose.Document {
  email: string;
  firstName: string;
  lastName: string;
  active: boolean;
  password: string;
  createdAt: Date;
  updatedAt: Date;
  organization: OrganizationDoc;
}

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      match: [/.+\@.+\..+/, 'Please fill a valid email address'],
    },
    firstName: {
      type: String,
      required: true,
      trim: true,
    },
    lastName: {
      type: String,
      required: true,
      trim: true,
    },
    active: {
      type: Boolean,
      default: true,
      required: true,
    },
    password: {
      type: String,
      required: true,
    },
    createdAt: {
      type: Date,
      required: true,
      default: Date.now,
    },
    updatedAt: {
      type: Date,
      required: true,
      default: Date.now,
    },
    organization: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Organization',
    },
  },
  {
    toJSON: {
      transform(_doc, ret) {
        ret.id = ret._id;
        delete ret._id;
        delete ret.password;
        delete ret.__v;
      },
    },
  }
);

userSchema.pre('save', async function (done) {
  if (this.isModified('password')) {
    const hashed = await Password.toHash(this.get('password'));
    this.set('password', hashed);
    this.set('updatedAt', Date.now);
  }
  done();
});

userSchema.statics.build = (attrs: UserAttrs) => {
  return new User(attrs);
};


const User = mongoose.model<UserDoc, UserModel>('User', userSchema);

export { User };

如果添加新用户,不会有任何麻烦:

// Create an organization
  const organization = Organization.build({
    id: mongoose.Types.ObjectId().toHexString(),
    name: 'Organization One',
  });
  await organization.save();
  
  const password = 'MySuperPassword';
  // Create a user 
  let user = User.build({
    email: 'test@organization-one.com',
    firstName: 'organization-one firstname',
    lastName: 'organization-one lastname',
    password: password,
    organization: organization.id, // Adding user to organization (link it actually)
  });
  await user.save();

如果要这样做,我想实现的是检索具有特定组织ID的所有用户:


router.get(
  '/:organizationId/users',
  requireAuth,
  async (req: Request, res: Response) => {

  const organizationId = req.params.organizationId;

  const users = await User.find({ organization: organizationId });

  res.status(200).send(users);
  }
);

我尝试过await User.find({ organization: new mongoose.Types.ObjectId(organizationId) });却没有运气...

编辑

唯一有效的方法(看起来不太干净)是将organizationalId强制转换为Object

const organizationId = req.params.organizationId as Object;

还有另一种方法吗?还是在这种情况下我应该从数据库中检索组织?

1 个答案:

答案 0 :(得分:0)

我在编写 Typescript 时通常使用 Typegoose ,但是由于 Typegoose 只是 Mongoose 的包装,认为以下陈述也可以为您提供帮助:

const users = await User.findById(organizationId);