Skip to main content

Class: Model<T, R>

Document class represents a database document and provides useful methods to work with.

Example

import { connect, model } from "ottoman";
connect("couchbase://localhost/travel-sample@admin:password");

// Create an `User` model
const User = model('User', { name: String });

// Create a document from the `User` Model
const jane = new User({ name: "Jane Doe" })

Type parameters

NameType
Tany
Rany

Hierarchy

Accessors

$isNew

get $isNew(): boolean

Boolean flag specifying if the document is new.

Example

const CardSchema = new Schema({
cardNumber: { type: String, immutable: true },
zipCode: String,
});

// Create model
const Card = model('Card', CardSchema);

// Create document
const myCard = new Card({ cardNumber: '4321 4321 4321 4321', zipCode: '43210' });
myCard.$isNew; // true

// Save document
const myCardSaved = await myCard.save();
myCardSaved.$isNew; // false

Returns

boolean

Inherited from

Document.$isNew

Defined in

model/document.ts:615

Methods

_applyData

_applyData(data, strategy?): Model<T, R>

Allows to easily apply data from an object to current document.

Example

const user = new User({ name: "John Doe" });

user._applyData({ name: "Jane Doe" });
console.log(user) // { name: "Jane Doe" }

Example

With strategies on immutable properties

const User = model('Card', { name: { type: String, immutable: true } });
const user = new User({ name: 'John Doe' });

// with strategy:false is like above example
user._applyData({ name: 'Jane Doe' }, false);
console.log(user); // { name: "Jane Doe" }

// with strategy:true remains immutable
user._applyData({ name: 'Jane Doe' }, true);
console.log(user); // { name: "John Doe" }

// trying to update it directly
user.name = 'Jane Doe';
console.log(user); // { name: "John Doe" }

// with strategy:CAST_STRATEGY.THROW
user._applyData({ name: 'Jane Doe' }, CAST_STRATEGY.THROW);
// ImmutableError: Field 'name' is immutable and current cast strategy is set to 'throw'

Parameters

NameTypeDefault value
dataanyundefined
strategyApplyStrategytrue

Returns

Model<T, R>

Inherited from

Document._applyData

Defined in

model/document.ts:524


_depopulate

_depopulate(fieldsName): Model<T, R>

Reverts population. Switches back document reference.

Example

To get in context about the Card and Issue Models see the populate example..

const card = await Card.findById(cardId);
console.log(card.issues); // ['issueId']

await card._populate('issues')
console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]

card._depopulate('issues')
console.log(card.issues); // ['issueId']

Parameters

NameType
fieldsNamestring | string[]

Returns

Model<T, R>

Inherited from

Document._depopulate

Defined in

model/document.ts:440


_getId

_getId(): string

Returns id value, useful when working with dynamic ID_KEY.

Example

  console.log(user._getId()); // 'userId'
console.log(user.id); // 'userId'

Returns

string

Inherited from

Document._getId

Defined in

model/document.ts:124


_getIdField

_getIdField(): string

Returns id key.

Returns

string

Inherited from

Document._getIdField

Defined in

model/document.ts:131


_populate

_populate(fieldsName?, options?): Promise<Model<T, R>>

Allows to load document references.

Example

Getting context to explain populate.

// Defining the schemas
const addressSchema = new Schema({
address: String,
});
const personSchema = new Schema({
name: String,
age: Number,
address: { type: addressSchema, ref: 'Address' },
});
const companySchema = new Schema({
president: { type: personSchema, ref: 'Person' },
ceo: { type: personSchema, ref: 'Person' },
name: String,
workers: [{ type: personSchema, ref: 'Person' }],
});

// Initializing the models
const Address = model('Address', addressSchema);
const Person = model('Person', personSchema);
const Company = model('Company', companySchema);

// Adding some data
const johnAddress = await Address.create({ address: '13 Washington Square S, New York, NY 10012, USA' });
const john = await Person.create({ name: 'John Smith', age: 52, address: johnAddress });

const janeAddress = await Address.create({ address: '55 Clark St, Brooklyn, NY 11201, USA' });
const jane = await Person.create({ name: 'Jane Doe', age: 45, address: janeAddress });

const company = await Company.create({ name: 'Space X', president: john, ceo: jane });

// Getting saved company data
const spaceX = await Company.findById(company.id);
console.log(`Company: `, company);

Will get:

Company: {
name: 'Space X',
president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
ceo: '32c2e85a-cc91-4db2-935f-f7d2768168de',
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Now we will see how the _populate methods works.

const result = await spaceX._populate('ceo');
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
ceo: {
name: 'Jane Doe',
age: 45,
address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
_type: 'Person'
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Can also pass an array or a string separated by a comma

const result = await spaceX._populate('ceo,president');
// or
const result = await spaceX._populate(['ceo', 'president']);
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: {
name: 'John Smith',
age: 52,
address: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
id: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
_type: 'Person'
},
ceo: {
name: 'Jane Doe',
age: 45,
address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
_type: 'Person'
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

If you want to get only a portion of the object

const result = await spaceX._populate({
ceo: ['age', 'address'], // or 'age,addres'
president: 'name',
});
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: { name: 'John Smith' },
ceo: { age: 45, address: '235dd441-b445-4b88-b6aa-2ce35a958a32' },
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Now let's to go deeper

const result = await spaceX._populate(
{
ceo: {
select: 'age,id', // remember you can use ['age','address']
populate: 'address', // will populate all the fields
},
president: {
select: 'name',
populate: {
address: 'address', // will populate address field only
},
},
},
2, // for populate up to the second level
);
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: {
name: 'John Smith',
address: { address: '13 Washington Square S, New York, NY 10012, USA' }
},
ceo: {
age: 45,
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
address: {
address: '55 Clark St, Brooklyn, NY 11201, USA',
id: '235dd441-b445-4b88-b6aa-2ce35a958a32',
_type: 'Address'
}
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Below is another way through the find functions

const result = await Company.findOne(
{ name: 'Space X' },
{
select: 'president,ceo',
populate: {
president: { select: 'address,id', populate: 'address' },
ceo: { select: ['age', 'name'], populate: { address: { select: 'id' } } },
},
populateMaxDeep: 2,
},
);
console.log(`Result: `, result);
Result: {
ceo: {
age: 45,
name: 'Jane Doe',
address: { id: '235dd441-b445-4b88-b6aa-2ce35a958a32' }
},
president: {
address: {
address: '13 Washington Square S, New York, NY 10012, USA',
id: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
_type: 'Address'
},
id: '50e85ac9-5b4f-4587-aeb6-b287527794c9'
}
}

Parameters

NameType
fieldsName?PopulateFieldsType
options?PopulateOptionsType

Returns

Promise<Model<T, R>>

Inherited from

Document._populate

Defined in

model/document.ts:418


_populated

_populated(fieldName): boolean

Allows to know if a document field is populated.

Example

To get in context about the Card and Issue Models see the populate example..

const card = await Card.findById(cardId);
console.log(card.issues); // ['issueId']
console.log(card._populated('issues')); // false

await card._populate('issues')
console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]
console.log(card._populated('issues')); // true

Parameters

NameType
fieldNamestring

Returns

boolean

Inherited from

Document._populated

Defined in

model/document.ts:480


_validate

_validate(): any

Runs schema validations over current document.

Example

const user = new User( { name: "John Doe" } );

try {
await user._validate()
} catch(errors) {
console.log(errors)
}

Returns

any

Inherited from

Document._validate

Defined in

model/document.ts:568


remove

remove(options?): Promise<any>

Removes the document from the database.

Example

const user = User.findById('userId')

await user.remove();

Parameters

NameType
optionsremoveOptions

Returns

Promise<any>

Inherited from

Document.remove

Defined in

model/document.ts:208


save

save(onlyCreate?, options?): Promise<any>

Saves or Updates the document.

Example

const user = new User({ name: "John Doe" }); //user document created, it's not saved yet

await user.save(); // user saved into the DB

// You also can force save function to only create new Documents by passing true as argument
await user.save(true); // ensure to execute a insert operation

Parameters

NameTypeDefault value
onlyCreatebooleanfalse
optionssaveOptions{}

Returns

Promise<any>

Inherited from

Document.save

Defined in

model/document.ts:148


toJSON

toJSON(): Model<T, R>

Returns a Javascript object to be serialized to JSON

Returns

Model<T, R>

Inherited from

Document.toJSON

Defined in

model/document.ts:582


toObject

toObject(): Model<T, R>

Returns a Javascript object with data

Returns

Model<T, R>

Inherited from

Document.toObject

Defined in

model/document.ts:575