Data Personalization Example

This guide walks you through the process of creating an application that demonstrates to the concept of data personalization.

What you’ll build

An oeCloudbased app with a model autoscoped on organization and will post data with manual scopes to that model.

What you’ll need

  • You should have Node and NPM installed.
  • mod headers extension installed on google chrome.You can get it here

How to start with this guide

You can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you.

To start from the scratch go to Getting Started

Basic terms and their definition.

Term Description
autoscope A setting in model.json where developer can force model to be automatically scoped at certain parameter. Specified as an array of strings in model definition.
scope While POSTing the data user can specify a scope manually by adding a json attribute named scope : {}
_scope A final calculated scope which will be stored in the database. The final _scope will be a combination of autoscope and Manual Scope. _scope will be stored as an array of Integer bit positions reserved on first come first serve basis.
Weightages Weightages specified on request may be as an additional header. These weightages will be used while calculating the score while retrieving the records.
score The final value calculated based on weightages of the matched records. The record with highest score will be given priority over the next highest score and so on.

Getting started

  1. First we will create a model with autoscope organization.

        {
            "name": "Customer",
            "base": "BaseEntity",
            "strict": false,
            "idInjection": false,
            "options": {
                "validateUpsert": true
            },
            "properties": {
                "name": {
                    "type": "string",
                    "required": true
                }
            },
            "hidden": [],
            "validations": [],
            "relations": {},
            "acls": [],
            "methods": {},
            "autoscope": [
                "organization"
            ]
        }
    
    • Refresh the screen so that you can see your newly created model.

    Observation: The model definition contains a property autoscope which is used to autoscope a model on some contributor.

  2. We will post data with manual scopes in it.

    • In mod headers plugin set request headers with name= organization and value= ev
    • Use api POST/Customers and post the following data.
        [
            {
                "name": "noScopeRecord"
            },
            {
                "name": "1manualScopes-device",
                "scope": {
                  "device": "mobile"
                }
            },
            {
                "name": "2manualScopes-location-device",
                "scope": {
                  "device": "desktop",
                  "location": "in"
                }
            },
            {
                "name": "1manualScopes-lang",
                "scope": {
                  "lang": "en-in"
                }
            },
            {
                "name": "2manualScopes-lang-device",
                "scope": {
                  "lang": "en-us",
                  "device": "mobile"
                }
            },
            {
                "name": "2manualScopes-lang-location",
                "scope": {
                  "location": "us",
                  "lang": "en-us"
                }
            },
            {
                "name": "3manualScopes-location-lang-device",
                "scope": {
                  "location": "in",
                  "lang": "en-in",
                  "device": "mobile"
                }
            }
        ]
    
    • Your data should be successfully posted to customer model.
  3. GETting the data from the customer model

    • Use api GET/Customers .

    Output

        {
        "error": {
            "name": "Error",
            "status": 500,
            "message": "insufficient data, Autoscoped values not found Customer",
            "txnId": "312e3110-2d3b-11e6-ace8-2f475f854141"
            }
        }
    

Observations : As customer model is autoscoped on organization and organization value not provided, so you wont get any records.

  1. GETting the data from the customer model

    • In mod headers plugin set request headers with name= organization and value= ev
    • Use api GET/Customers .

    Output

        [
            {
                "name": "noScopeRecord",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            }
        ]
    

    Observations : As all the other records are scopes at some value and we are not providing any value so we won’t get any scoped record.

  2. GETting the data from the customer model - In mod headers plugin set request headers with the following

```
    organization=ev
    device= mobile
```
- Use api `GET/Customers` .

**Output**

```javascript
    [
        {
            "name": "noScopeRecord",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
        {
            "name": "1manualScopes-device",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        }
    ]
```
**observations** : provided scope is `device= mobile` in mod headers, so the record with `1manualScopes-device` also comes as result.
  1. GETting the data from the customer model

    • In mod headers plugin set request headers with the following
    organization=ev
    device= desktop
    location= in
    
    • Use api GET/Customers .

    output :

        [
            {
                "name": "noScopeRecord",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            },
            {
                "name": "2manualScopes-location-device",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            }
        ]
    

    observations : provided scope is device= desktop & location= in in mod headers, so the record with 2manualScopes-location-device also comes as result.

  2. GETting the data from the customer model

    • In mod headers plugin set request headers with the following
    organization=ev
    device= desktop
    location= in
    x-ctx-weight-location = 20
    x-ctx-weight-device = 30
    
    • Use api GET/Customers .

    output

        [
            {
                "name": "2manualScopes-location-device",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            },
            {
                "name": "noScopeRecord",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            }
        ]
    

    observations : provided scope is device= desktop & location= in in mod headers, so the record with 2manualScopes-location-device also comes as result. Also the result is sorted based on the weights provided.

  3. GETting the data from the customer model

    • In mod headers plugin set request headers with the following
    organization=ev
    device= desktop
    location= us
    
    • Use api GET/Customers.

    Output

        [
            {
                "name": "noScopeRecord",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            }
        ]
    

    observations : provided scope is device= desktop & location= us in mod headers, so the record with noManualScope comes as result as there are no other matching records for such contrubutor values.

  4. GETting the data from the customer model

    • In mod headers plugin set request headers with the following
    organization=ev
    device= desktop
    location= us
    
    • Use api GET/Customers with filter value as {"where":{"scope.location":"in"}}.

    Output

        [
            {
                "name": "2manualScopes-location-device",
                "id": "*****",
                "_version": "***-***-*******",
                "_type": "Customer",
                "_createdBy": "demouser",
                "_modifiedBy": "demouser",
                "_createdOn": "2016-**-****:**:**.****",
                "_modifiedOn": "2016-**-****:**:**.****"
            }
        ]
    

    observations : provided scope is device= desktop & location= us in mod headers, but we are applying additional filter saying "scope.location":"in", so the manually passed filter takes the priority over the headers values.

  5. GETting the data from the customer model - In mod headers plugin set request headers with the following

```
organization=ev
device= mobile
location= in
lang = en-in
x-ctx-weight-device= 30
x-ctx-weight-location= 20
x-ctx-weight-lang= 50
```
- Use api `GET/Customers` with filter value as `{"where":{"scope.location":"in"}}`.

**Output**
```javascript
    [
        {
            "name": "3manualScopes-location-lang-device",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "1manualScopes-lang",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "1manualScopes-device",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "noScopeRecord",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        }
    ]
```
**Observation:** All the records whose scope is subset of execution scope will be present in the result.
  1. GETting the data from the customer model - In mod headers plugin set request headers with the following
```
organization=ev
device= mobile
location= in
lang = en-in
x-ctx-weight-device= 30
x-ctx-weight-location= 20
x-ctx-weight-lang= 50
X-ignore-context=["lang"]
```
- Use api `GET/Customers` with filter value as `{"where":{"scope.location":"in"}}`.

**Output**
```javascript
    [
        {
            "name": "3manualScopes-location-lang-device",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "1manualScopes-device",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "noScopeRecord",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        },
         {
            "name": "1manualScopes-lang",
            "id": "*****",
            "_version": "***-***-*******",
            "_type": "Customer",
            "_createdBy": "demouser",
            "_modifiedBy": "demouser",
            "_createdOn": "2016-**-****:**:**.****",
            "_modifiedOn": "2016-**-****:**:**.****"
        }
    ]
```
 
> __Note__ Observe the order of records in the result of step 10 and 11.
 
**Observation:** All the records whose scope is subset of execution scope will be present in the result. 
The header `x-ignore-context` will be used to ignore contributor value for calculation of score while sorting. 

summary

Congratulations!! You have successfully completed the guide on various concepts of data personalization.