不填充嵌套数组的ref对象

时间:2020-05-14 10:25:36

标签: mongodb typescript mongoose nestjs mongoose-populate

我正在使用以下项目:

    "@nestjs/core": "^7.0.0",
    "@nestjs/mongoose": "^7.0.0",
    "mongoose": "^5.9.12",
    // ...
    "typescript": "^3.7.4",

使用mongoose / mongoDB配置:

      uri: MONGO_DB_URI,
      useUnifiedTopology: true,
      useNewUrlParser: true,
      useFindAndModify: false,
      useCreateIndex: true,

我正在尝试为此模型构建简单CRUD

export const ContactSchema = new mongoose.Schema(
  {
    source_id: { type: String, required: true },
    firstName: { type: String, trim: true },
    lastName: { type: String, trim: true },
    phones: [
      {
        number: {
          type: String,
          required: true,
          unique: true,
          validate: {
            validator: function(value) {
              const phoneNumber = parsePhoneNumberFromString(value)
              return phoneNumber && phoneNumber.isValid()
            },
          },
        },
        type: {
          type: String,
          default: function() {
            return parsePhoneNumberFromString(this.number).getType() || "N/A"
          },
        },
        code: {
          type: Number,
          default: function() {
            return parsePhoneNumberFromString(this.number).countryCallingCode || undefined
          },
        },
        national: {
          type: Number,
          default: function() {
            return parsePhoneNumberFromString(this.number).nationalNumber || undefined
          },
        },
      },
    ],
    email: { type: String, unique: true, required: true, lowercase: true, trim: true },
  },
  { timestamps: true },
)

ContactSchema.plugin(mongoosePaginate)

就像每个CRUD应用程序一样,我愿意使用fildAll()fildOne()路由来返回给定Contact 的主体及其所有信息,包括其列表电话号码。所以我用:

  // ...
  async findAll(): Promise<Contact[]> {
    return this.contactModel.find()
    // then I add
    .populate('phones')
  }

  async findBySourceId(id: string): Promise<Contact> {
    return this.contactModel.findOne({ source_id: id })
    // then I add
    .populate('phones')
  }
  // ...

所有信息都很好地保存在数据库中,并且没有丢失的数据(两个电话都没有),而且我敢肯定,即使没有添加.poplate('x'),它也可以开始工作,但是在某个地方发生了变化,并且它返回了现在已不填充电话阵列

现在返回:

    {
        "_id": "5ebc22072e18637d84bcf6f0",
        "firstName": "Maher",
        "lastName": "Boubakri",
        "phones": [],
        "email": "mhb@test.im",
        // ...
    }

但是,它应该返回:

    {
        "_id": "5ebc22072e18637d84bcf6f0",
        "firstName": "Maher",
        "lastName": "Boubakri",
        "phones": [
            {
                "_id": "5ebc22072e18637d8fd948f9",
                "number": "+21622123456",
                "code": 216,
                "type": "MOBILE",
                "national": 22123456,
            }
        ],
        "email": "mhb@test.im",
        // ...
    }

注意:很明显,MongoDB为每个电话对象生成_id,但它不是引用对象。

任何想法都会很有帮助,

谢谢。

2 个答案:

答案 0 :(得分:2)

populate用于使用引用将两个(或多个)集合连接起来

在这里您没有任何参考,因此您不需要

仅使用find()而不使用populate

答案 1 :(得分:0)

根据@Mohammed 的评论和回答,更新.lean() 后添加mongoose 解决了问题。

// ...
  async findAll(): Promise<Contact[]> {
    return this.contactModel.find().lean()
  }

  async findBySourceId(id: string): Promise<Contact> {
    return this.contactModel.findOne({ source_id: id }).lean()
  }
// ...