Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.97k stars 3.84k forks source link

Populate with match and transform included nulls in result #11434

Closed SergioArrighi closed 2 years ago

SergioArrighi commented 2 years ago

Do you want to request a feature or report a bug? I am not sure, sorry

What is the current behavior? I'm using populate function to load objects into an array of my model. I'm also using match to filter these objects.

Now I want to apply a function to the filtered list, but as soon as I use transform field of populate options I get a null value for each excluded object in output

If the current behavior is a bug, please provide the steps to reproduce.

  1. Create a schema
  2. Create another schema with an array of string referring to other schema
  3. Execute a find with populate on the ref field with a match condition
  4. Try to apply transform
  5. Verify that non matching objects are added as null

tsconfig.json { "compilerOptions": { "module": "commonjs", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "target": "es2017", "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true, "skipLibCheck": true, "strictNullChecks": false, "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false } }

What is the expected behavior? Populate transform is applied only to objects which satisfy the match condition.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version. Nodejs 17.4.0 MongoDB 5.0.4 Community Mongoose 6.1.7

IslandRhythms commented 2 years ago

Can you provide the line where you make the populate call?

IslandRhythms commented 2 years ago
const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: String
});

const otherSchema = new mongoose.Schema({
    array: [{type: mongoose.Schema.Types.ObjectId, ref: 'Test'}]
});

const Other = mongoose.model('Other', otherSchema);

const Test = mongoose.model('Test', testSchema);

async function run() {
await mongoose.connect('mongodb://localhost:27017');
await mongoose.connection.dropDatabase();

const entry = await Test.create({
    name: 'Test'
});

const entry2 = await Test.create({
    name: 'Other Test'
});

await Other.create({
    array:[entry._id, entry2._id]
});
await Other.create();

const result = await Other.find({$match: {array: entry._id}}).populate('array');
console.log('the result', result);

result.forEach((entry) => {
    console.log(entry.array[0],'and', entry.array[1])
});

}

run();