Skip to content

Commit 510e622

Browse files
docs: add Union SchemaType documentation without formatting changes
1 parent ee6a377 commit 510e622

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

docs/schematypes.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Check out [Mongoose's plugins search](http://plugins.mongoosejs.io) to find plug
4848
* [Buffer](#buffers)
4949
* [Boolean](#booleans)
5050
* [Mixed](#mixed)
51+
* [Union](#union)
5152
* [ObjectId](#objectids)
5253
* [Array](#arrays)
5354
* [Decimal128](api/mongoose.html#mongoose_Mongoose-Decimal128)
@@ -68,6 +69,7 @@ const schema = new Schema({
6869
updated: { type: Date, default: Date.now },
6970
age: { type: Number, min: 18, max: 65 },
7071
mixed: Schema.Types.Mixed,
72+
union: { type: Schema.Types.Union, of: [String, Number] },
7173
_someId: Schema.Types.ObjectId,
7274
decimal: Schema.Types.Decimal128,
7375
double: Schema.Types.Double,
@@ -720,6 +722,117 @@ The following inputs will result will all result in a [CastError](validation.htm
720722
* a decimal that must be rounded to be an integer
721723
* an input that represents a value outside the bounds of an 32-bit integer
722724

725+
### Union {#union}
726+
727+
The `Union` SchemaType allows a path to accept multiple types. Mongoose will attempt to cast the value to one of the specified types.
728+
```javascript
729+
const schema = new Schema({
730+
value: {
731+
type: Schema.Types.Union,
732+
of: [String, Number]
733+
}
734+
});
735+
736+
const Model = mongoose.model('Model', schema);
737+
738+
// Both work - Mongoose accepts either type
739+
const doc1 = new Model({ value: 'hello' });
740+
const doc2 = new Model({ value: 42 });
741+
```
742+
743+
#### Casting Behavior
744+
745+
When you set a value on a Union path, Mongoose tries to cast it to each type in the `of` array in order. If the value matches one of the types exactly (using `===`), Mongoose uses that value. Otherwise, Mongoose uses the first type that successfully casts the value.
746+
```javascript
747+
const schema = new Schema({
748+
flexibleField: {
749+
type: Schema.Types.Union,
750+
of: [Number, Date]
751+
}
752+
});
753+
754+
const Model = mongoose.model('Model', schema);
755+
756+
// Number type
757+
const doc1 = new Model({ flexibleField: 42 });
758+
doc1.flexibleField; // 42 (number)
759+
760+
// String '42' gets cast to Number (first type that succeeds)
761+
const doc2 = new Model({ flexibleField: '42' });
762+
doc2.flexibleField; // 42 (number)
763+
764+
// Date type
765+
const doc3 = new Model({ flexibleField: new Date('2025-06-01') });
766+
doc3.flexibleField; // Date object
767+
768+
// String date gets cast to Date
769+
const doc4 = new Model({ flexibleField: '2025-06-01' });
770+
doc4.flexibleField; // Date object
771+
```
772+
773+
#### Error Handling
774+
775+
If Mongoose cannot cast the value to any of the specified types, it throws the error from the last type in the union.
776+
```javascript
777+
const schema = new Schema({
778+
value: {
779+
type: Schema.Types.Union,
780+
of: [Number, Boolean]
781+
}
782+
});
783+
784+
const Model = mongoose.model('Model', schema);
785+
786+
const doc = new Model({ value: 'not a number or boolean' });
787+
// Throws: Cast to Boolean failed for value "not a number or boolean"
788+
```
789+
790+
#### Union with Options
791+
792+
You can specify options for individual types in the union, such as `trim` for strings.
793+
```javascript
794+
const schema = new Schema({
795+
value: {
796+
type: Schema.Types.Union,
797+
of: [
798+
Number,
799+
{ type: String, trim: true }
800+
]
801+
}
802+
});
803+
804+
const Model = mongoose.model('Model', schema);
805+
806+
const doc = new Model({ value: ' hello ' });
807+
doc.value; // 'hello' (trimmed)
808+
```
809+
810+
#### Queries and Updates
811+
812+
Union types work with queries and updates. Mongoose casts query filters and update operations according to the union types.
813+
```javascript
814+
const schema = new Schema({
815+
value: {
816+
type: Schema.Types.Union,
817+
of: [Number, String]
818+
}
819+
});
820+
821+
const Model = mongoose.model('Model', schema);
822+
823+
await Model.create({ value: 42 });
824+
825+
// Query with string - gets cast to number
826+
const doc = await Model.findOne({ value: '42' });
827+
doc.value; // 42
828+
829+
// Update
830+
await Model.findOneAndUpdate(
831+
{ value: 42 },
832+
{ value: 'hello' }
833+
);
834+
```
835+
723836
## Getters {#getters}
724837

725838
Getters are like virtuals for paths defined in your schema. For example,

0 commit comments

Comments
 (0)