Worklight :: JSONStore :: How to work with additio

2019-08-15 18:16发布

问题:

I'm using Worklight6.2 and I have a small problem related with JSONStores.

I have several on my application to aid me relating to my relational model on a third party database. To properly work with this paradigm I'm trying to use several search indexes to find documents inside my store. Let's say I have a store with this aspect

var data = {GUID: 'XPTO-XPTZ-FOO', product_name= 'potatos'}

Sometimes I want to access my object by GUID some other times I want to access it by product_name. So I would have a

var searchField = {GUID: 'string'};
var additionalSearchField = {product_name: 'string'};

Thing is, when I use this additionalSearchField it doesn't find my potatos. I would like to use additionalSearchField to avoid JSONStore recreations.

I think that I'm not using additional Search Fields the way they were intended, but I'm having trouble wrapping my head about its concept.

From IBM Documentation:

Additional search fields are keys that are indexed but that are not part of the JSON data that is stored. These fields define the key whose values (in a given JSON collection) are indexed and can be used to search more quickly.

http://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.1.0/com.ibm.worklight.dev.doc/devref/r_jsonstore_search_fields.html

Can someone help me understand how they work?

回答1:

You should use the product_name as part of the initialization of that collection, so you will have two search fields UID and product_name, i.e.:

var collections = {
    products : {
        searchFields: {UID: "string", product_name: "string"}
    }
};


WL.JSONStore.init(collections);

Then you can go ahead and do the searching, i.e.:

$("#searchByUID").on("click", function(){
    var needle = $("#search").val();

    var query = {
        UID: needle
    };

    var collectionName = 'products';
    var options = {
        exact: true,
        limit: 10 //max of 10 docs
    }; 

    WL.JSONStore.get(collectionName).find(query, options)
    .then(function (results) {
        // handle your results
    })
    .fail(function (errorObject) {
        // handle error
    });
});

You could also do the same for the product_name

$("#searchByProductName").on("click", function(){
    var needle = $("#search").val();

    var query = {
        product_name: needle
    };

    // ...
});


回答2:

Here's an example of additional search fields being used to create a key/value store like localStorage.

var KEY_VALUE_COLLECTION_NAME = 'keyvalue';

var collections = {};

//Define the 'keyvalue' collection and use additional search fields
collections[KEY_VALUE_COLLECTION_NAME] = {
    searchFields : {},
    additionalSearchFields : { key: 'string' }
};

WL.JSONStore.init(collections);
//I skipped the success and failure callbacks

//The code bellow assumes that the 'keyvalue' collection has been initialized.

var value = 'myValue';
var key = 'myKey';
WL.JSONStore.get(KEY_VALUE_COLLECTION_NAME).add({key: value}, {additionalSearchFields: {key: key}});
//I skipped the success and failure callbacks

//The code bellow assumes that add has finished sucesfully.

WL.JSONStore.get(KEY_VALUE_COLLECTION_NAME).find({key: key}, {exact: true, limit: 1});
//Should call the success callback with something like this: 
//[{_id: 1, json: {value: 'myValue'}}]

Take a look at the internal representation of the store in the docs.

If we imagine we added searchField1 and searchField2 instead of the empty object I used above, it would look like this:

+-----+-----------------------------+--------------+--------------+----------------------------------------+
| _id | key (additionalSearchField) | searchField1 | searchField2 | json                                   |
+-----+-----------------------------+--------------+--------------+----------------------------------------+
| 1   | myKey                       | a            | b            | {searchField1: 'a', searchField2: 'b'} |
+-----+-----------------------------+--------------+--------------+----------------------------------------+

Notice that myKey the value of the key (additional search field) is not part of the JSON object stored. That's why the documentation says:

Additional search fields are keys that are indexed but that are not part of the JSON data that is stored.

There's no easy way to change the columns of the table (i.e. search fields and additional search fields) once it has been created. That's why you run into this: -2 PROVISION_TABLE_SEARCH_FIELDS_MISMATCH. To change what is being indexed you need to write some migration code to move data to a new collection or remove the collection with the removeCollection or destroy APIs.