fogine/couchbase-odm

View on GitHub
tutorials/3b.refDocIndexes.md

Summary

Maintainability
Test Coverage
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) {
        //
    });
````