mongoose icon indicating copy to clipboard operation
mongoose copied to clipboard

Custom schema type & operators

Open mwenko opened this issue 2 weeks ago • 6 comments

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

mwenko avatar Nov 13 '25 08:11 mwenko

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.

markstos avatar Nov 13 '25 13:11 markstos

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.

@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 avatar Nov 13 '25 13:11 mwenko

@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.

markstos avatar Nov 13 '25 13:11 markstos

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:

  1. ✔️ Inherit from SchemaType
  2. ✔️ Implement the cast() method
  3. ✔️ 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.

markstos avatar Nov 13 '25 19:11 markstos

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 avatar Nov 14 '25 19:11 vkarpov15

@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 ?

markstos avatar Nov 14 '25 19:11 markstos

Using custom schema types because of the need to support geospatial query operators like $geoIntersects, can't do that with plain subdocuments

vkarpov15 avatar Nov 17 '25 15:11 vkarpov15

Thanks for the clarification!

markstos avatar Nov 17 '25 15:11 markstos