Skip to content
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

Aggregations with filters on ObjectIds fail in MongooseQueryService #881

Closed
h4rm opened this issue Feb 16, 2021 · 8 comments · Fixed by #1046
Closed

Aggregations with filters on ObjectIds fail in MongooseQueryService #881

h4rm opened this issue Feb 16, 2021 · 8 comments · Fixed by #1046
Labels
bug Something isn't working investigate mongoose Issues related to the mongoose package

Comments

@h4rm
Copy link

h4rm commented Feb 16, 2021

Version: 0.22

When a DTO has a reference which is specified as follows:

@ObjectType('Document')
export class DocumentDTO {
  @FilterableField(() => String, { nullable: true })
  userId?: Types.ObjectId;
}

and a schema

@Schema({ })
export class Document {
  @Prop({ type: SchemaTypes.ObjectId, ref: 'User', required: false })
  userId?: Types.ObjectId;
}

currently I cannot filter for the userId in an aggregation:

query countDocuments($filter: DocumentAggregateFilter) {
  documentAggregate(filter: $filter) {
    count {
      id
    }
  }
}

when I call countDocuments(filter: {userId:{eq: "123456"} }) because I get the following error:

TypeError: Cannot destructure property '_id' of 'undefined' as it is undefined.
    at Function.convertToAggregateResponse (/Users/ben/Documents/coding/dexter/server/node_modules/@nestjs-query/query-mongoose/dist/src/query/aggregate.builder.js:21:41)
    at DocumentService.aggregate (/Users/ben/Documents/coding/dexter/server/node_modules/@nestjs-query/query-mongoose/dist/src/services/mongoose-query.service.js:52:41)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async target (/Users/ben/Documents/coding/dexter/server/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)
    at async /Users/ben/Documents/coding/dexter/server/node_modules/@nestjs/core/helpers/external-proxy.js:9:24

Screen Shot 2021-02-16 at 17 34 09

Basically the mongoose aggregate function doesn't return a valid result here. Also, in some cases where the was no result to an aggregate query, I also got this error and not the number 0 as expected.

Filtering for other properties works and I can also filter for a specific userId in a normal query.
I think this is a bug with some unhandled case, but maybe I am misusing something.

@h4rm h4rm added the bug Something isn't working label Feb 16, 2021
@h4rm h4rm changed the title Aggregations with filters on ObjectIds fail Aggregations with filters on ObjectIds fail in MongooseQueryService Feb 16, 2021
@h4rm
Copy link
Author

h4rm commented Feb 16, 2021

This is probably due to the fact that aggregate expects the following:

document.aggregate([
  {
    $match: { userId: ObjectId('1234') }
  }
])

@doug-martin Any plans on extending the aggregate query builder to convert fields of type ID to the mongoose ObjectId?

@doug-martin
Copy link
Owner

@h4rm thank you for the bug report and tracking down what's causing it, that helps a lot! There will need to be some investigation on how to identify the fields that should be turned into an objectId. @smolinari do you know a way of doing this?

@doug-martin doug-martin added mongoose Issues related to the mongoose package investigate labels Feb 16, 2021
@h4rm
Copy link
Author

h4rm commented Feb 17, 2021

So I dug a little bit deeper and overwrite the aggregate in my DocumentService.

Two things actually fix the problem:

Number 1

Replace all string Ids to by the same ObjectIds. I am doing it manually right now but I think it should be possible to gather that information from the schema somehow and do it automatically in the buildAggreateQuery which uses the default buildFilterQuery internally. Maybe I could get help on that.

Number 2

Call convertToAggregateRepsonse as followed to prevent the above mentioned error when the mongoose aggregate returns an empty array:

    return AggregateBuilder.convertToAggregateResponse({ _id: null, ...aggResult[0] });

This will result in the counts to return as null. Of course, the nicest thing would be to return 0 for all aggregates but at least the request doesn't crash in that case.

@smolinari
Copy link
Collaborator

@doug-martin - I'm not so deep into the inner workings of Mongoose. The person who might know better is @JohnMcInall.

Scott

@doug-martin
Copy link
Owner

@h4rm this has been fixed in v0.25.1!

@h4rm
Copy link
Author

h4rm commented Apr 7, 2021 via email

@smolinari
Copy link
Collaborator

Yes. Thanks so much for covering this Doug.

Scott

@h4rm
Copy link
Author

h4rm commented Apr 7, 2021

@doug-martin Is it possible that the same problem persists on the subscription part of the filters? I was secretly hoping it's using the same code underneath :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working investigate mongoose Issues related to the mongoose package
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants