mongoose
mongoose copied to clipboard
Custom schema type & operators
Prerequisites
- [x] I have written a descriptive issue title
Mongoose version
8.19.3
Node.js version
22
MongoDB version
7
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
No response
Issue
I'm using a mongoose plugin that defines a custom GeoJson schema type by extending mongoose schema.
And I use it like so:
serviceAreaGeometry: { type: mongoose.Schema.Types.MultiPolygon },
Then I had a test case which used a query that uses $geoIntersects which resulted in the following error:
Error: Can't use $geoIntersects.
Do I need to add those operators to an "allow list" (= $conditionalHandlers) of the schema? I'm asking because I haven't found any documentation for it, but only studied the source code which looks like I need to do so.
Here is the related PR I made for that plugin: https://github.com/echoes-xyz/mongoose-geojson-schema/pull/61
I don't find a mention of "Can't use" in the mongoose code base, so Mongoose is not throwing that error. I found one mention of the error on StackOverflow. In that case, that geometry was malformed, which caused the MongoDB database, not Mongoose, to complain:
https://stackoverflow.com/questions/40325288/mongodb-geointersects-cannot-find-polygons-that-contain-a-given-point
I'll look at the linked issue to see about reproducing the issue.
I don't find a mention of "Can't use" in the
mongoosecode base, so Mongoose is not throwing that error. I found one mention of the error on StackOverflow. In that case, that geometry was malformed, which caused the MongoDB database, not Mongoose, to complain:https://stackoverflow.com/questions/40325288/mongodb-geointersects-cannot-find-polygons-that-contain-a-given-point
I'll look at the linked issue to see about reproducing the issue.
@markstos It's in the codebase of mongoose. But it might have been missed in your searches because the error message contains an escape character.
See this line: https://github.com/Automattic/mongoose/blob/51dd78339f8b7b6c772c8587573957fabb5ff1f3/lib/schemaType.js#L1692
@mwenko You are right about the escape character. Great find. In that case, this appears to be either a Mongoose regression or an undocumented breaking change, as the plugin has worked for years until we tried to upgrade to Mongoose 8. Maybe we can contribute a new (failing) test to the Mongoose test suite that covers this case.
In comparing this Mongoose plugins with others and the docs, the GeoJSON plugin isfollowing the docs on how to create a a custom schema type. It meets the three requirements:
- ✔️ Inherit from SchemaType
- ✔️ Implement the cast() method
- ✔️ Add the corresponding property to mongoose.Schema.Types.
It's possible that because GeoJSON represents a nested object and not just a "type" of a single thing, maybe "custom types" have been the wrong way to handle this all along, and the better pattern to use is an embedded doc. That's the guidance at the top of the "Custom Schema Type" page:
Before you reach for a custom type, however, know that a custom type is overkill for most use cases. You can do most basic tasks with custom getters/setters, virtuals, and single embedded docs.
The syntax for users would be practically identical.
You're right, the fix is to add $geoIntersects to $conditionalHandlers for that schematype. I left a comment on the https://github.com/echoes-xyz/mongoose-geojson-schema/pull/61#pullrequestreview-3466592357 PR
@vkarpov15 Thanks for the feedback. For the case of GeoJSON, which are nested objects, do you think the better approach is to continue to validate GeoJSON using complex types, or better to validate them with sub-document schemas, an alternative that I created with a draft PR here. https://github.com/echoes-xyz/mongoose-geojson-schema/pull/64 ?
Using custom schema types because of the need to support geospatial query operators like $geoIntersects, can't do that with plain subdocuments
Thanks for the clarification!