Model Relations
In this section, we’ll go through how relations work in NimbusDB and how to define and manage them in your models. We’ll use items and shop models for our examples.
// `items` modelitems = new NimbusDBModel("global", "items", { id: { type: NIMBUSDB_DATA_TYPE.INTEGER, const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY }, name: NIMBUSDB_DATA_TYPE.STRING, price: { type: NIMBUSDB_DATA_TYPE.NUMBER, validator: function(data, value) { return value >= 0; }, default_value: 0 }, is_locked: { type: NIMBUSDB_DATA_TYPE.BOOLEAN, const: NIMBUSDB_CONSTRAINT.OPTIONAL, default_value: false }}, [ { id: 1, name: "Apple", price: 5 }, { id: 2, name: "Banana", price: 7.2 }, { id: 3, name: "Cherry", price: 15 }, { id: 4, name: "Date", price: 12.5 }, { id: 5, name: "Elderberry", price: 8 }, { id: 6, name: "Fig", price: 10 }, { id: 7, name: "Grape", price: 6 }, { id: 8, name: "Honeydew", price: 9 }, { id: 9, name: "Kiwi", price: 4 }, { id: 10, name: "Lemon", price: 3 }]);
// `shop_items` modelshop_items = new NimbusDBModel("global", "shop_items", { id: { type: NIMBUSDB_DATA_TYPE.INTEGER, const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY }, item_id: NIMBUSDB_DATA_TYPE.INTEGER, stock: NIMBUSDB_DATA_TYPE.INTEGER}, [ { id: 1, item_id: 1, stock: 20 }, { id: 2, item_id: 2, stock: 17 }, { id: 3, item_id: 3, stock: 23 }, { id: 4, item_id: 3, stock: 50 }, { id: 5, item_id: 5, stock: 10 }]);Defining Relations
Section titled “Defining Relations”NimbusDB provides a simple way to define relations between models, either in models or catalogs.
One-Way Relations
Section titled “One-Way Relations”A “blind” relation that defined one-sided. In other words, the target model has no knowledge of the source model.
// define relation from shop_items.item_id to items.idvar rel_id = shop_items.define_relation(items, "item_id", "id");
// in case you want to to get the relation id latervar shop_items_rel = shop_items.get_relation("items", "item_id", "id");Based on the example above, we got this:
┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━┓┃ shop_items ┃ ┃ items ┃┣━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━┫│ id │ ┌─────>│ id │├──────────────┤ │ ├───────────┤│ item_id │──────┘ │ name │├──────────────┤ ├───────────┤│ stock │ │ price │└──────────────┘ ├───────────┤ │ is_locked │ └───────────┘item_id column in shop_items model is the foreign key that points to the id column in items model.
As you can see, it just one-way relation. So, later we can resolve shop_items.item_id to items.id, but we can’t resolve items.id to shop_items.item_id. We’ll cover this in Data Resolving section.
Bidirectional Relations
Section titled “Bidirectional Relations”A mutual relation between two models. Both models will have knowledge of each other.
// define relation from shop_items.item_id to items.idshop_items.define_relation(items, "item_id", "id");
// and then from items.id to shop_items.item_iditems.define_relation(shop_items, "id", "item_id");Based on the example above, we got this:
┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━┓┃ shop_items ┃ ┃ items ┃┣━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━┫│ id │ ┌─────>│ id │├──────────────┤ │ ├───────────┤│ item_id │<─────┘ │ name │├──────────────┤ ├───────────┤│ stock │ │ price │└──────────────┘ ├───────────┤ │ is_locked │ └───────────┘We can resolve both shop_items.item_id to items.id and items.id to shop_items.item_id.
Explanation
Section titled “Explanation”For the example above, we got 2 different perspectives:
-
From
shop_itemsmodel perspective:shop_itemsmodel needsitemsmodel’s data throughitem_idcolumn.- With this, we have “The first item in the
shop_itemswill sell which item?”-like question.
-
From
itemsmodel perspective:itemsmodel hasshop_itemsmodel’s data throughidcolumn.- With this, we have “Which shop sells this item?” or “Where do I get this item?” question.
Relations in Catalog
Section titled “Relations in Catalog”If you’re using catalog, you can define relations cleaner. Let’s use this catalog:
ctg_items = new NimbusDBCatalog("shop_catalog", { model: [items, shop]});One-Way Relations
Section titled “One-Way Relations”// define relation from shop_items.item_id to items.idctg_items.define_relation("shop_items", "item_id", "items", "id"); // using model name and column name
ctg_items.define_relation("shop_items.item_id = items.id"); // using model-column stringctg_items.define_relation([ // using array of model-column strings "shop_items.item_id = items.id", "...relN"]);
ctg_items.define_relation({ // using relation selector, array of this object is also allowed from: "shop_items", // `from` and `to` can be model name, custom id, or model instance from_column: "item_id", // `from_column` and `to_column` must be string (the column name) to: "items", to_column: "id"});Bidirectional Relations
Section titled “Bidirectional Relations”// define relation from shop_items.item_id to items.id and vice versa
// when using `.define_relation()`, set `bidirectional: true` option// works on any style/format that is accepted by `.define_relation()`ctg_items.define_relation("shop_items", "item_id", "items", "id", { bidirectional: true});
// you can also use the bidirectional operators insteadctg_items.define_relation("shop_items.item_id <=> items.id");
// or use `.define_mutual_relation()` to enable the bidirectional relation by defaultctg_items.define_mutual_relation("shop_items", "item_id", "items", "id");
ctg_items.define_mutual_relation("shop_items.item_id = items.id"); // using model-column stringctg_items.define_mutual_relation([ // using array of model-column strings "shop_items.item_id = items.id", "...relN"]);
ctg_items.define_mutual_relation({ // using relation selector, array of this object is also allowed from: "shop_items", // `from` and `to` can be model name, custom id, or model instance from_column: "item_id", // `from_column` and `to_column` must be string (the column name) to: "items", to_column: "id"});Relation Operators
Section titled “Relation Operators”If you’re using string-selector format for defining relations ("model1.from_col {operator} model2.to_col"), you can use the following operators:
| Operator | Type | Description |
|---|---|---|
=, ->, => | One-way | Defines a relation from left model to right model. |
<-, <= | One-way | Defines a relation from right model to left model. |
<->, <=> | Bidirectional | Defines a relation from left model to right model and vice versa. |
// using one-way operator// from left (source) to right (target)ctg_items.define_relation("shop_items.item_id = items.id");ctg_items.define_relation("shop_items.item_id -> items.id");ctg_items.define_relation("shop_items.item_id => items.id");
// from right (source) to left (target)ctg_items.define_relation("shop_items.item_id <- items.id");ctg_items.define_relation("shop_items.item_id <= items.id");
// using bidirectional operatorctg_items.define_relation("shop_items.item_id <-> items.id");ctg_items.define_relation("shop_items.item_id <=> items.id");References
Section titled “References”NimbusDBRelation Internal
Section titled “NimbusDBRelation ”Represents a defined relationship between two models, linking a column in the source model to a column in the target model.
class NimbusDBRelation { constructor( _model: NimbusDBModel, _name_id: string | int, _from_column: string, _to_column: string, _options?: NimbusDBRelationOptions )
custom_id: int | undefined; from_column: string; id: int; is_primary: boolean; model: NimbusDBModel | undefined; name: string | undefined; to_column: string;
static __id: int;}Model.define_relation()
Section titled “Model.define_relation()”Defines a one-way relation between models.
Signature
Section titled “Signature”class NimbusDBModel { // ... other methods and properties ... static define_relation( _to_model: NimbusDBModel, _from_column: string, _to_column: string, _option?: NimbusDBRelationOptions ): int | NimbusDBRelation;}Parameters
Section titled “Parameters”_to_model
Section titled “_to_model”- Type:
NimbusDBModel - The target model of this relation.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
_options
Section titled “_options”- Type:
NimbusDBRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation - The relation id. If
return_objectoption is set totrue, returns theNimbusDBRelationinstance.
Model.drop_relation()
Section titled “Model.drop_relation()”Drops a one-way relation from the model.
Signature
Section titled “Signature”class NimbusDBModel { // ... other methods and properties ... static drop_relation( _relation_id: int ): void;}Parameters
Section titled “Parameters”_relation_id
Section titled “_relation_id”- Type:
int - The id of the relation to drop. Can be obtained from
.define_relation()or.get_relation().
Signature
Section titled “Signature”class NimbusDBModel { // ... other methods and properties ... static drop_relation( _model_name_id: string | int, _from_column: string, _to_column: string ): void;}Parameters
Section titled “Parameters”_model_name_id
Section titled “_model_name_id”- Type:
string|int - The name or custom ID of the model.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
Model.get_relation()
Section titled “Model.get_relation()”Retrieves a relation from the model.
Signature
Section titled “Signature”class NimbusDBModel { // ... other methods and properties ... static get_relation( _model_name_id: string | int, _from_column: string, _to_column: string, _options?: NimbusDBGetRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_model_name_id
Section titled “_model_name_id”- Type:
string|int - The name or custom ID of the model.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
_options
Section titled “_options”- Type:
NimbusDBGetRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Signature
Section titled “Signature”class NimbusDBModel { // ... other methods and properties ... static get_relation( _relation_id: int, _options?: NimbusDBGetRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_relation_id
Section titled “_relation_id”- Type:
int - The id of the relation to retrieve. Can be obtained from
.define_relation()or.get_relation().
_options
Section titled “_options”- Type:
NimbusDBGetRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Catalog.define_relation()
Section titled “Catalog.define_relation()”Defines a directional relation between two models using a selector string or object.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static define_relation( _from_model: string, _from_column: string, _to_model: string, _to_column: string, _options?: NimbusDBCatalogRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_from_model
Section titled “_from_model”- Type:
string - The source model name.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_model
Section titled “_to_model”- Type:
string - The target model name.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
_options
Section titled “_options”- Type:
NimbusDBCatalogRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static define_relation( _selector: | string | string[] | NimbusDBRelationSelector | NimbusDBRelationSelector[], _options?: NimbusDBCatalogRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_selector
Section titled “_selector”- Type:
string|string[]|NimbusDBRelationSelector|NimbusDBRelationSelector[] - Selector string(s) in format
"model1.col = model2.col", or aNimbusDBRelationSelectorobject or array of it.
_options
Section titled “_options”- Type:
NimbusDBCatalogRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Catalog.define_mutual_relation()
Section titled “Catalog.define_mutual_relation()”Defines a bidirectional relation between two models using a selector string or object.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static define_mutual_relation( _from_model: string, _from_column: string, _to_model: string, _to_column: string, _options?: NimbusDBCatalogRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_from_model
Section titled “_from_model”- Type:
string - The source model name.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_model
Section titled “_to_model”- Type:
string - The target model name.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
_options
Section titled “_options”- Type:
NimbusDBCatalogRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static define_mutual_relation( _selector: | string | string[] | NimbusDBRelationSelector | NimbusDBRelationSelector[], _options?: NimbusDBCatalogRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_selector
Section titled “_selector”- Type:
string|string[]|NimbusDBRelationSelector|NimbusDBRelationSelector[] - Selector string(s) in format
"model1.col = model2.col", or aNimbusDBRelationSelectorobject or array of it.
_options
Section titled “_options”- Type:
NimbusDBCatalogRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Catalog.drop_relation()
Section titled “Catalog.drop_relation()”Drops a relation between two models.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static drop_relation( _from_model: string | int | NimbusDBModel, _from_column: string, _to_model: string | int | NimbusDBModel, _to_column: string ): void;}Parameters
Section titled “Parameters”_from_model
Section titled “_from_model”- Type:
string|int|NimbusDBModel - The source model name, custom id, or model instance.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_model
Section titled “_to_model”- Type:
string|int|NimbusDBModel - The target model name, custom id, or model instance.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static drop_relation( _model: string | int | NimbusDBModel, _relation_id: int ): void;}Parameters
Section titled “Parameters”_model
Section titled “_model”- Type:
string|int|NimbusDBModel - The model name, custom id, or model instance.
_relation_id
Section titled “_relation_id”- Type:
int - The relation id.
Catalog.get_relation()
Section titled “Catalog.get_relation()”Retrieves a relation between two models.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static get_relation( _from_model: string | int | NimbusDBModel, _from_column: string, _to_model: string | int | NimbusDBModel, _to_column: string, _options?: NimbusDBGetRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_from_model
Section titled “_from_model”- Type:
string|int|NimbusDBModel - The source model name, custom id, or model instance.
_from_column
Section titled “_from_column”- Type:
string - The column in the source model used for the join.
_to_model
Section titled “_to_model”- Type:
string|int|NimbusDBModel - The target model name, custom id, or model instance.
_to_column
Section titled “_to_column”- Type:
string - The column in the target model used for the join.
_options
Section titled “_options”- Type:
NimbusDBGetRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
Signature
Section titled “Signature”class NimbusDBCatalog { // ... other methods and properties ... static get_relation( _relation_id: int, _options?: NimbusDBGetRelationOptions ): int | NimbusDBRelation | undefined;}Parameters
Section titled “Parameters”_relation_id
Section titled “_relation_id”- Type:
int - The relation id.
_options
Section titled “_options”- Type:
NimbusDBGetRelationOptions - Default:
undefined - Optional configuration for the relation.
Returns
Section titled “Returns”- Type:
int|NimbusDBRelation|undefined - The relation id. Returns
NimbusDBRelationinstance ifreturn_objectoption is set totrue. Returnsundefinedif the relation cannot be found.
NimbusDBRelationSelector
Section titled “NimbusDBRelationSelector”type NimbusDBRelationSelector = { from: string | int | NimbusDBModel; // int = model's custom_id from_column: string; to: string | int | NimbusDBModel; // int = model's custom_id to_column: string; options?: NimbusDBGetRelationOptions;};NimbusDBRelationOptions
Section titled “NimbusDBRelationOptions”Optional configurations for the relation.
type NimbusDBRelationOptions = Partial<{ is_primary: boolean; // whether the target model's column is a primary key for that model (default = false) use_custom_id: boolean; // use custom_id instead of name (default = false)}>;NimbusDBGetRelationOptions
Section titled “NimbusDBGetRelationOptions”Optional configurations for .get_relation() method.
type NimbusDBGetRelationOptions = Partial<{ return_object: boolean; // return relation object instead of system id (default = false) temporary: boolean; // force creating new relation and don't store in relations array (default = false) use_custom_id: boolean; // use custom_id instead of name (default = false)}>;NimbusDBCatalogRelationOptions
Section titled “NimbusDBCatalogRelationOptions”Optional configurations for .define_relation() and .define_mutual_relation() methods.
type NimbusDBCatalogRelationOptions = Partial<{ bidirectional: boolean; // make the relation bidirectional (default = false)}> & NimbusDBGetRelationOptions;