# Class: Document ‹T

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

T

# Hierarchy

# Methods

# _applyData

_applyData(data: any, strategy: ApplyStrategy): void

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:

Name Type Default
data any -
strategy ApplyStrategy true

Returns: void


# _depopulate

_depopulate(fieldsName: string | string[]): this

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:

Name Type
fieldsName string | string[]

Returns: this


# _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


# _getIdField

_getIdField(): string

Returns id key.

Returns: string


# _populate

_populate(fieldsName?: PopulateFieldsType, deep: number): Promise‹this›

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:

Name Type Default
fieldsName? PopulateFieldsType -
deep number 1

Returns: Promise‹this›


# _populated

_populated(fieldName: string): 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:

Name Type
fieldName string

Returns: boolean


# _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


# remove

remove(options: object): Promise‹any›

Removes the document from the database.

example

const user = User.findById('userId')

await user.remove();

Parameters:

Name Type Default
options object {}

Returns: Promise‹any›


# save

save(onlyCreate: boolean): Promise‹this›

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:

Name Type Default
onlyCreate boolean false

Returns: Promise‹this›


# toJSON

toJSON(): this

Returns a Javascript object to be serialized to JSON

Returns: this


# toObject

toObject(): this

Returns a Javascript object with data

Returns: this