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
Model with discriminatorKey throws error in aggregation pipeline when performing a search #12478
Comments
You are not encountering this error when commenting out |
No I am not because mongoose will automatically add the param
So any search I perform using the Child model satisfies the search index requirements even if I don't expressly add a partition field to the query myself. This is the case for any query. A simple Which is great. I'm totally fine with that. The issue arises in the aggregation pipeline if I have specifically set the partition param myself. I realize it's not necessary to set it myself but I wouldn't expect it to insert an extra $match stage above my search stage (which necessitates being first). Instead, I would expect mongoose to drop its automatically generated partition filter if it sees that one already exists in the pipeline's first stage. |
Forgot I was dropping the db on each run and that deletes indexes. import { Schema, model, connect, connection } from 'mongoose';
// setup a parent schema with a discriminatorKey
const ParentSchema: Schema = new Schema(
{
title: String,
description: String,
},
{
discriminatorKey: 'partition',
}
);
// create search index on the title and description fields
ParentSchema.index({
partition: 1,
title: 'text',
description: 'text',
});
// create child schema to inherit from parent
const ChildSchema: Schema = new Schema(
{
type: String,
},
{
discriminatorKey: 'partition',
}
);
// create models
const Parent = model('Parent', ParentSchema);
Parent.discriminator('Child', ChildSchema);
const Child = model('Child');
(async function () {
await connect('mongodb://localhost:27017');
await connection.dropDatabase();
await Parent.init();
// insert a child document to search for
await Child.create({
title: 'Hello World',
description: 'This is a test',
type: 'Test',
});
// search for child document using the aggregation pipeline
await Child.aggregate([
{
$match: {
// partition: 'Child',
$text: {
$search: 'test',
},
},
},
]);
console.log('done');
// MongoServerError: $match with $text is only allowed as the first pipeline stage
})(); |
…t discriminator key to correct value in first pipeline stage Fix #12478
The issue is that |
fix(aggregate): avoid adding extra `$match` stage if user manually set discriminator key to correct value in first pipeline stage
Prerequisites
Mongoose version
6.3.1
Node.js version
14
MongoDB server version
4.4.0
Description
If you are trying to use the aggregation pipeline to search a Model that has a discriminatorKey, this error is thrown because the discriminatorKey's match phase is automatically injected into the pipeline before the search's match phase.
$match with $text is only allowed as the first pipeline stage
Steps to Reproduce
Clearly I put $text in the first pipeline stage but mongoose injects its own discriminatorKey match into the pipeline ahead of mine and produces this in mongo:
If I remove the partition param from my $match, then mongoose's $match is merged into mine and it works:
Produces this in mongo...
Expected Behavior
If the first pipeline stage is a $match, Mongoose should always merge its discriminatorKey params into the first stage instead of inserting an additional $match above it. If the first stage already contains a discriminatorKey param then the auto-generated params from Mongoose should be dropped.
The text was updated successfully, but these errors were encountered: