RefDoc Indexes

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) {
        //
    });
comments powered by Disqus