首页 > 解决方案 > 是否有可能在 Mongodb(使用 mongoose 和 typegoose)中有一个嵌套键数组的索引?

问题描述

在 mongodb 中(使用 mongoose 和 typegoose)是否可以在嵌套键上有一个数组索引?

export class Member extends Typegoose {
  @prop({ required: true })
  public email!: string;

  @prop({ required: true })
  private userId!: string
}

@index({ 'members.userId': 1 })
export class Group {
  @arrayProp({ items: Member })
  public members: Member[];

  @prop()
  name: string;
}

如果是这样,如果我想通过 userId 查找组,我该如何查询这个集合?像这样?

Group.findOne({ usersIds: userId })

标签: mongodbmongoosetypegoose

解决方案


是的,这是可能的,您可以这样做:

// NodeJS: 14.5.0
// MongoDB: 4.2-bionic (Docker)
import { getModelForClass, prop, index } from "@typegoose/typegoose"; // @typegoose/typegoose@7.3.0
import * as mongoose from "mongoose"; // mongoose@5.9.25 @types/mongoose@5.7.32

class Member {
  @prop({ required: true })
  public email!: string;
}

@index({ "members.email": 1 }, { unique: true }) // added unique to be easily testable 
class Group {
  @prop({ type: Member })
  public members?: Member[];

  @prop()
  public name?: string;
}

const GroupModel = getModelForClass(Group);

(async () => {
  await mongoose.connect(`mongodb://localhost:27017/`, { useNewUrlParser: true, dbName: "verifyMASTER", useCreateIndex: true, useUnifiedTopology: true });

  await GroupModel.create({ name: "group1", members: [{ email: "h@h.h" }] });
  try {
    await GroupModel.create({ name: "group2", members: [{ email: "h@h.h" }] });
    console.log("didnt fail");
  } catch (err) {
    // it should error
    console.log("err", err);
  }

  console.log(await GroupModel.listIndexes());

  await mongoose.disconnect();
})();

输出GroupModel.listIndexes

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'verifyMASTER.groups' },
  {
    v: 2,
    unique: true,
    key: { 'members.email': 1 },
    name: 'members.email_1',
    ns: 'verifyMASTER.groups',
    background: true
  }
]

推荐阅读