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.
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
:
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:
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:
{
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
//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) {
//
});