-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
match within .populate is working incorrectly. #10117
Comments
Yes. Have the same issue. |
what are you updating exactly when you run |
We've been looking into this and found some more info. Your query, as written, is not expected to work because The more correct populate uses await Organization.findById(org).populate({
path: 'administrators',
match: {
access: {
$elemMatch: { role: 'admin', deletedAt: { $exists: false } }
}
},
}); However, this does come with a nuance because this will find users where Also, it turns out there's an issue where the below script shows that 'use strict';
const mongoose = require('mongoose');
mongoose.set('debug', true);
mongoose.set('useFindAndModify', false);
const { Schema } = mongoose;
run().catch(err => console.log(err));
async function run() {
await mongoose.connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true
});
await mongoose.connection.dropDatabase();
const User = mongoose.model('User', mongoose.Schema({
name: String,
access: [{ role: String, deletedAt: Date, organization: 'ObjectId' }]
}));
const organizationSchema = mongoose.Schema({ name: String });
organizationSchema.virtual('administrators', {
ref: 'User',
localField: '_id',
foreignField: 'access.organization'
});
const Organization = mongoose.model('Organization', organizationSchema);
const org = await Organization.create({ name: 'test org' });
await User.create([
{ name: 'user1', access: [{ role: 'admin', organization: org._id }] },
{ name: 'user2', access: [{ role: 'admin', organization: null }] },
{ name: 'user3', access: [{ role: 'admin', organization: org._id, deletedAt: new Date() }, { role: 'admin', organization: org._id }] }
]);
const res = await Organization.findById(org).populate({
path: 'administrators',
match: {
access: { $elemMatch: { role: 'admin', deletedAt: { $exists: false } } }
},
});
console.log(res.administrators);
} |
…to avoid duplicate docs in result Re: #10117
Do you want to request a feature or report a bug?
bug
What is the current behavior?
Given the following model (using typegoose but it can be easily reproduces with plain mongoose too)
Now in access array I have the following:
Then I have another model with virtual populate like this
When I do
I expect it to find the above user because it has one of access items where deletedAt does not exist;
Instead it filters out that user which seems very unintuitive and unexpected.
If the current behavior is a bug, please provide the steps to reproduce.
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node", "express"],
"target": "es5",
"sourceMap": true,
"alwaysStrict": true,
"noImplicitAny": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true,
"noResolve": false,
"moduleResolution": "node",
"typeRoots": ["./node_modules/@types"]
},
"exclude": ["/*.spec.ts", "/.d.ts", "**/tests/utils/.ts"],
"include": ["**/*.ts"]
What is the expected behavior?
match should keep user with access like this
because one of items matches with organization and. does not have deletedAt field
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
node 14
mongoose 5.10
mongodb 3.6.5
The text was updated successfully, but these errors were encountered: