tutorials/3b.refDocIndexes.md
Reference document is a document referencing parent document with it's value which is the document we search for.
Parent (main) document can have many (**unique**) reference documents which are maintained along with the parent document so everything is up to date.
<img src="./refdoc_example1.png" />
To define collection of reference documents associated to the main document, specify a `Map` of definitions under the `options.indexes.refDocs` option of a `Model`:
````javascript
const User = couchbase.define('User', {
type: 'object',
required: ['email'],
properties: {
username: {type: 'string'},
email : {type: 'string'}
}
}, {
indexes: {
refDocs: {
username: {keys: ['username']} //Defines refDoc with key `User_username_{username-value}` for each user document
}
}
})
````
The above refDoc definition creates `getByUsername` method on `User` model, so later on you can do:
````javascript
return User.getByUsername('happiecat').then(function(user) {
console.log(user.username); // $ > happiecat
console.log(user.email); // $ > bla@bla.com
});
````
Note that defined refDoc indexes are required by default, so (considering above `User` model definition example) when you try to save an user with empty `username` property, it will try to build a key for the reference document and fail with a `KeyError`, despite `username` property in Model schema definition is set as optional.
To resolve the issue you may set `required=false` option property in the refDoc definition:
````javascript
{
indexes: {
refDocs: {
username: {
keys: ['username'],
required: false // if insert/update process fails key generation for the refDoc, the refDoc wont be created and `User.getByUsername` returns rejected promise with storage "not found" error
}
}
}
}
````
#### More complex refDocs definition example with pseudo composite unique index
<img src="./refdoc_example2.png" />
````javascript
//Model definition
const User = couchbase.define('User', {
type: 'object',
properties: {
username: { type: 'string' },
recovery: {
type: 'object',
properties: {
id: {type: 'integer'}
}
},
}
}, {
indexes: {
refDocs: {
recoveryAccount: {keys: ['username', 'recovery.id']} //Defines refDoc with key `User_username_{username-value}_recovery.id_{id-value}` for each user document
}
}
});
//get recovery account
return User.getByRecoveryAccount(['happiecat', 43092]).then(function(user) {
//
});
````