Mercury Fields
In Mercury, fields are the building blocks of your data models. They define the structure and types of data that can be stored in each model. This guide provides a detailed explanation of field types and their properties in Mercury.
Field Types and Structure
Mercury uses TypeScript types to define the structure of fields in a model. Here are the key types:
type TFields = {
[fieldName: string]: TField;
};
type TField = {
type:
| 'string'
| 'number'
| 'float'
| 'boolean'
| 'relationship'
| 'enum'
| 'virtual'
| 'mixed'
| 'date';
ref?: string;
enum?: Array<string | number>;
enumType?: string;
required?: boolean;
unique?: boolean;
many?: boolean;
localField?: string;
foreignField?: string;
bcrypt?: boolean;
rounds?: number;
ignoreGraphQL?: boolean;
default?: any;
[x: string]: any;
};
TFields
TFields
is a type that represents the structure of all fields in a model. It's an object where each key is the name of a field, and the corresponding value is of type TField
.
TField
TField
is a type that defines the structure of an individual field. It includes the following properties:
type
(Required): Specifies the data type of the field. It must be one of the supported Mercury types: 'string', 'number', 'float', 'boolean', 'relationship', 'enum', 'virtual', 'mixed', or 'date'.ref
(Optional): Used for 'relationship' fields to specify the referenced model.enum
(Optional): An array of allowed values for 'enum' fields.enumType
(Optional): Specifies the type of enum values ('string' or 'number').required
(Optional): A boolean indicating if the field is mandatory.unique
(Optional): A boolean indicating if each value for this field must be unique across all documents.many
(Optional): A boolean used for 'relationship' fields to indicate a one-to-many relationship.localField
(Optional): Used for 'virtual' fields to specify the local field for population.foreignField
(Optional): Used for 'virtual' fields to specify the foreign field for population.bcrypt
(Optional): A boolean indicating if the value should be encrypted using bcrypt (for 'string' fields).rounds
(Optional): The number of bcrypt rounds for encryption.ignoreGraphQL
(Optional): A boolean to exclude the field from GraphQL schemas.default
(Optional): Sets a default value for the field.[x: string]: any
: Allows for additional Mongoose-supported properties to be included.
Here's a detailed explanation of each field option:
-
ref
: string- Used with 'relationship' type fields.
- Specifies the name of the model that this field references.
- Example:
ref: 'User'
in a 'Post' model to reference the 'User' model.
-
enum
: Array- Used with 'enum' type fields.
- Defines an array of allowed values for the field.
- Example:
enum: ['admin', 'user', 'guest']
.
-
enumType
: string- Specifies the type of values in the enum array ('string' or 'number').
- Example:
enumType: 'string'
for string enums,enumType: 'number'
for numeric enums.
-
required
: boolean- If true, the field must have a value when saving a document.
- Example:
required: true
.
-
unique
: boolean- If true, ensures that no two documents in the collection have the same value for this field.
- Example:
unique: true
.
-
many
: boolean- Used with 'relationship' type fields.
- If true, indicates a one-to-many relationship (the field will be an array of references).
- Example:
many: true
.
-
localField
: string- Used with 'virtual' type fields.
- Specifies the field in the current model to match against in virtual population.
- Example:
localField: '_id'
.
-
foreignField
: string- Used with 'virtual' type fields.
- Specifies the field in the referenced model to match against in virtual population.
- Example:
foreignField: 'author'
.
-
bcrypt
: boolean- If true, the field's value will be encrypted using bcrypt before saving.
- Typically used for password fields.
- Example:
bcrypt: true
.
-
rounds
: number- Used in conjunction with
bcrypt
. - Specifies the number of bcrypt hashing rounds.
- Example:
rounds: 10
.
- Used in conjunction with
-
ignoreGraphQL
: boolean- If true, this field will be excluded from GraphQL schemas.
- Useful for fields that shouldn't be exposed via API.
- Example:
ignoreGraphQL: true
.
-
default
: any- Sets a default value for the field if no value is provided.
- Can be a static value or a function.
- Example:
default: 'Unknown'
ordefault: () => new Date()
.
-
[x: string]: any
- This is a TypeScript index signature.
- It allows for additional Mongoose-supported properties to be included.
- Enables the use of any valid Mongoose SchemaType options not explicitly defined in Mercury.
Supported Field Types
Mercury supports the following field types:
string
: For text datanumber
: For integer valuesfloat
: For decimal numbersboolean
: For true/false valuesrelationship
: For references to other modelsenum
: For fields with a predefined set of valuesvirtual
: For computed fields that don't persist in the databasemixed
: For fields that can hold any type of datadate
: For date and time values
These types are mapped to Mongoose types as follows:
string
→String
number
→Number
float
→Number
boolean
→Boolean
relationship
→ObjectId
or[ObjectId]
enum
→String
orNumber
with enum validationvirtual
→ Mongoose virtual fieldmixed
→mongoose.Schema.Types.Mixed
date
→Date
Only these types are directly supported by Mercury.js. For other Mongoose types, you can use the mixed
type and handle the specifics in your application logic.
Additional Mongoose-Supported Properties
Important: Mercury's flexibility extends beyond its built-in field options!
Mercury provides a robust set of field properties, but it is not limited to these. The [x: string]: any
index signature in the TField
type allows for the inclusion of any additional Mongoose-supported SchemaType options in Mercury models.
This capability enables the use of any valid Mongoose SchemaType options not explicitly defined in Mercury, providing fine-grained control over data models.
For example, you might want to use Mongoose-specific validators, transformers, or other advanced options:
{
email: {
type: 'string',
required: true,
unique: true,
lowercase: true, // Mongoose-specific option
validate: { // Custom Mongoose validator
validator: function(v) {
return /^\S+@\S+\.\S+$/.test(v);
},
message: props => `${props.value} is not a valid email address!`
}
}
}
To explore the full range of available SchemaType options and unleash the full potential of your Mercury models, we recommend checking out the Mongoose SchemaType Options documentation.
By combining Mercury's simplicity with Mongoose's power, you can create highly customized and efficient data models for your applications.
Field Types and Usage
Mercury field types are mapped to Mongoose types as follows:
Basic Types
-
String
- Mercury:
string
- Mongoose:
String
- Usage:
fieldName: {
type: 'string'
}
- Mercury:
-
Number
- Mercury:
number
- Mongoose:
Number
- Usage:
fieldName: {
type: 'number'
}
- Mercury:
-
Float
- Mercury:
float
- Mongoose:
Number
- Usage:
fieldName: {
type: 'float'
}
- Mercury:
-
Boolean
- Mercury:
boolean
- Mongoose:
Boolean
- Usage:
fieldName: {
type: 'boolean'
}
- Mercury:
-
Date
- Mercury:
date
- Mongoose:
Date
- Usage:
fieldName: {
type: 'date'
}
- Mercury:
Complex Types
-
Relationship
- Mercury:
relationship
- Mongoose:
ObjectId
or[ObjectId]
- Usage:
fieldName: {
type: 'relationship',
ref: 'ModelName',
many: boolean // optional, default is false
} ref
: Specifies the name of the referenced modelmany
: If true, creates an array of ObjectIds (one-to-many relationship)
- Mercury:
-
Enum
- Mercury:
enum
- Mongoose:
String
orNumber
with enum validation - Usage:
fieldName: {
type: 'enum',
enumType: 'string' | 'number',
enum: ['VALUE1', 'VALUE2', ...] | [1, 2, ...],
default: 'VALUE1' | 1 // optional
} enumType
: Specifies whether the enum values are strings or numbersenum
: An array of allowed valuesdefault
: Optional default value from the enum array
- Mercury:
-
Virtual
- Mercury:
virtual
- Mongoose: Mongoose virtual field
- Usage:
fieldName: {
type: 'virtual',
ref: 'ModelName',
localField: 'localFieldName',
foreignField: 'foreignFieldName'
} ref
: The model to use for populationlocalField
: The field in the current model to match againstforeignField
: The field in the referenced model to match against- This creates a virtual field that can be populated with related documents
- Mercury:
-
Mixed
- Mercury:
mixed
- Mongoose:
mongoose.Schema.Types.Mixed
- Usage:
fieldName: {
type: 'mixed'
} - Allows any type of data to be stored in this field
- Mercury:
Examples
Here are some examples demonstrating the usage of different field types:
import mercury from "@mercury-js/core";
export const User = mercury.createModel(
"User",
{
name: {
type: "string",
required: true
},
age: {
type: "number",
min: 0,
max: 120
},
height: {
type: "float",
min: 0
},
isActive: {
type: "boolean",
default: true
},
birthDate: {
type: "date"
},
profilePic: {
type: "relationship",
ref: "Asset"
},
friends: {
type: "relationship",
ref: "User",
many: true
},
role: {
type: "enum",
enumType: "string",
enum: ["CUSTOMER", "VENDOR", "ADMIN"],
default: "CUSTOMER"
},
allocatedApartment: {
type: "virtual",
ref: "ApartmentAllocation",
localField: "_id",
foreignField: "customer"
},
additionalInfo: {
type: "mixed"
}
}
);
This example demonstrates the usage of all supported field types in Mercury, including basic types, relationships, enums, virtual fields, and mixed fields.
Remember that you can add any additional Mongoose-supported properties to these field definitions, and they will behave as they do in Mongoose. This flexibility allows you to fine-tune your schema according to your specific requirements.