mongodb 在mongoose中填充对象内部的数组

i2loujxw  于 2023-08-04  发布在  Go
关注(0)|答案(3)|浏览(120)

我有一个公司模型,看起来像这样:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const CompanySchema = new Schema(
  {
    companyName: String,
    settings: {
      type: {
        priceVisible: Boolean,
        allowPickupAddressAddition: Boolean,
        paymentMethodsAvailable: [
          { type: Schema.Types.ObjectId, ref: "PaymentMethod" },
        ],
      },
    },    
  }
);

const Company = mongoose.model("Company", CompanySchema);

module.exports = Company;

字符串
我想填充存储在paymentMethodsAvailable数组中的值。下面是相关的控制器代码:

const company = await Company.findOne({ _id: id }).populate([
      {
        path: "settings",
        populate: [{path: "paymentMethodsAvailable"}]
      },
    ]);


但这并不像预期的那样工作。我可以看到它可能试图填充设置对象,并在那里失败。有没有一种方法可以让mongoose填充settings.paymentMethodsAvailable

vhmi4jdf

vhmi4jdf1#

您应该注意type密钥:
type是Mongoose模式中的一个特殊属性。当Mongoose在模式中找到一个名为type的嵌套属性时,Mongoose假设它需要定义一个具有给定类型的SchemaType

  • 如果typesettings的嵌套属性,Mongoose模式应该是:
const CompanySchema = new mongoose.Schema({
    companyName: String,
    settings: {
        type: {
            type: {
                priceVisible: Boolean,
                paymentMethodsAvailable: [{ type: mongoose.Schema.Types.ObjectId, ref: 'PaymentMethod' }],
            },
        },
    },
});

// seed
const [p1] = await PaymentMethod.create([{ name: 'a' }, { name: 'b' }]);
const [c1] = await Company.create([
  {
    companyName: 'c-a',
    settings: {
      type: {
        priceVisible: true,
        paymentMethodsAvailable: [p1],
      },
    },
  },
]);

// populate
const company = await Company.findOne({ _id: c1?._id }).populate('settings.type.paymentMethodsAvailable');
console.log(util.inspect(company?.toObject(), false, null));

字符串
填充路径为settings.type.paymentMethodsAvailable
输出量:

{
  settings: {
    type: {
      priceVisible: true,
      paymentMethodsAvailable: [
        {
          _id: new ObjectId("64abce807233874fe5733d10"),
          name: 'a',
          __v: 0
        }
      ],
      _id: new ObjectId("64abce807233874fe5733d15")
    }
  },
  _id: new ObjectId("64abce807233874fe5733d14"),
  companyName: 'c-a',
  __v: 0
}

  • 如果type不是settings的嵌套属性,Mongoose模式与您的类似:
const CompanySchema = new mongoose.Schema({
    companyName: String,
    settings: {
        type: {
            priceVisible: Boolean,
            paymentMethodsAvailable: [{ type: mongoose.Schema.Types.ObjectId, ref: 'PaymentMethod' }],
        },
    },
});

// seed
const [p1] = await PaymentMethod.create([{ name: 'a' }, { name: 'b' }]);
const [c1] = await Company.create([
  {
    companyName: 'c-a',
    settings: {
      priceVisible: true,
      paymentMethodsAvailable: [p1],
    },
  },
]);

// populate
const company = await Company.findOne({ _id: c1?._id }).populate('settings.paymentMethodsAvailable');
console.log(util.inspect(company?.toObject(), false, null));


填充路径为settings.paymentMethodsAvailable
输出量:

{
  _id: new ObjectId("64abd00acd28f4120a317c2e"),
  companyName: 'c-a',
  settings: {
    priceVisible: true,
    paymentMethodsAvailable: [
      {
        _id: new ObjectId("64abd00acd28f4120a317c2a"),
        name: 'a',
        __v: 0
      }
    ],
    _id: new ObjectId("64abd00acd28f4120a317c2f")
  },
  __v: 0
}

kse8i1jr

kse8i1jr2#

试试这个

const company = await Company.findOne({ _id: id }).populate(
    "settings.paymentMethodsAvailable"
);

字符串
您可以在文档中找到更多示例。我使用这一节作为参考https://mongoosejs.com/docs/populate.html#populating-maps

brc7rcf0

brc7rcf03#

Mongoose提供了清晰的语法,下面的代码可以正常工作

const company = await Company.findOne({ _id: id }).populate(
    "settings.type.paymentMethodsAvailable"
);

if(!company) {
    // if there is no company with that id
    // this acully not error it's simply
    // return `null` to tell you company not found.
    res.status(404).send()
}

字符串
另外:您可以更进一步,在settings.paymentMethodsAvailable中填充特定字段

const company = await Company.findOne({ _id: id }).populate(
    "settings.type.paymentMethodsAvailable",
    "field1 filed2 filed3"
);

相关问题