mongodb-js / mongoose-autopopulate

Always populate() certain fields in your mongoose schemas
Apache License 2.0
222 stars 36 forks source link

Auto populate 2d array field containing discriminated schema #82

Closed JanKaczmarkiewicz closed 3 years ago

JanKaczmarkiewicz commented 3 years ago

Feature request It is possible to auto populate 2d array field containing discriminated schema?:

const enemySchema = new Schema({
    name: {
        required: true,
        type: String,
    },
    imageUrl: {
        required: true,
        type: String,
    },
    description: {
        required: true,
        type: String,
    },
    level: {
        required: true,
        type: Number,
    },
});

model("Enemy", enemySchema)

const mapSchema = new Schema({
    tiles: [[new Schema({}, { discriminatorKey: "kind", _id: false })]],
});

const contentPath = mapSchema.path('tiles.$');

contentPath.discriminator(
    'Enemy',
    new Schema(
        { enemy: { type: Schema.Types.ObjectId, ref: Model.Enemy, required: true, autopopulate: true } },
        {
            _id: false,
        },
    ),
);

contentPath.discriminator(
    'Wall',
    new Schema(
        { color: { type: String, required: true } },
        {
            _id: false,
        },
    ),
);

mapSchema.plugin(mongooseAutopopulate);

What is the expected behaviour? The discriminated field in arrays are auto-populated during queries

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version. mongoose: 5.11.14 mongoose-autopopulate: 0.12.3 node: 15.7.0

vkarpov15 commented 3 years ago

We did some work to support embedded discriminators, but we're gonna have to do some more work to support multidimensional arrays. Thanks for your patience :+1:

vkarpov15 commented 3 years ago

Fix will be in 0.13.0 and require Mongoose >= 5.12.4. Below is the syntax:

    const enemySchema = new Schema({
      name: String,
      level: Number
    });
    const Enemy = db.model('Enemy', enemySchema);

    const mapSchema = new Schema({
      tiles: [[new Schema({}, { discriminatorKey: 'kind', _id: false })]]
    });

    const contentPath = mapSchema.path('tiles');

    contentPath.discriminator('Enemy', new Schema({
      enemy: { type: Schema.Types.ObjectId, ref: 'Enemy', autopopulate: true }
    }));
    contentPath.discriminator('Wall', new Schema({ color: String }));
    mapSchema.plugin(autopopulate);
JanKaczmarkiewicz commented 3 years ago

@vkarpov15 Thank You very much <3