Databases and caches go hand in hand and have been in a close association for a long time now. Caches as the middle tier reduce pressure on your databases by keeping your data in the cache for faster processing. NCache is an in-memory distributed caching solution for your .NET and Java applications. For years, NCache has been providing high performance and scalability by reducing the load on the databases. It also ensures faster response time for your mission critical applications.
JSON has been one of the most famous data interchange formats between modern applications. It is a platform independent, lightweight and very readable and comprehendible language due to its patterned nature. It is extremely fast and can be used by modern programming languages and is supported by all major JavaScript frameworks.
Talking about the above mentioned two things separately brings us to our topic of discussion here which is the support of JSON in NCache. NCache being extremely scalable and distributed supports JSON data storage in the cache along with JSON serialization of your data. You can store a JSON document in the cache for fast and easy manipulation. NCache provides its own classes for JSON data storage, derived from an abstract class JsonValueBase based on their properties. These classes are:
- JsonValue
- JsonObject
- JsonArray
- JsonNull
NCache Details Cache Operations in NCache
Quick JSON Example between .NET & Java
For starters, let us look at a quick example showing the usage of JSON data in NCache. You can add a JSON document in your cache using a .NET application and this data can be retrieved by a Java application as JSON is platform independent.
The example given below shows the addition of a JSON document in your cache as a JsonObject using .NET.
1 2 3 4 5 6 7 8 9 10 |
// Pre-Condition: Cache is JSON serialized // The data provided in the string is a jsonObject string jsonString = "{ 'ProductID' : 1001, 'ProductName' : 'Chai', 'Category': 'Beverages', 'UnitPrice' : 500, 'UnitsInStock' : 2000 }"; // Populate an instance of the JsonObject by passing the string var jsonProduct = new JsonObject(jsonString); // Insert the jsonObject in the cache with a key string key = “Product:ProductID:1001”; cache.Insert(key, jsonProduct); |
The JSON document added above can be retrieved using a Java application. The code given below shows retrieval of the same JSON documents through Java. It further removes the attributes of the JsonObject and then re-inserts the JsonObject in the cache.
1 2 3 4 5 6 7 |
JsonObject jsonProduct = cache.get(key, JsonObject.class); // Remove the attribute UnitPrice from the JsonObject boolean result = jsonProduct2.removeAttribute("UnitPrice"); // Re-insert the item in the cache with the removed attribute cache.insert(key, jsonProduct); |
JSON Support in NCache
NCache is the primary caching solution that allows adding custom data in your cache and retrieving it in JSON format. Similarly, you can add JSON data in cache and retrieve it as a custom data object.
As mentioned earlier, NCache provides its own classes derived from JsonValueBase and these classes are then further used to add different formats of JSON data in the cache. We will take a closer look at these classes one by one:
1. JsonValue
JsonValue represents the primitive data types in JSON’s conventions. You can add value of any primitive type including others such as string, DateTime or decimal in .NET as JsonValue in the cache.
1 2 3 4 5 |
string keyInt = $"Product:{product.ProductID}"; JsonValue jsonValue = 1001; // Insert a JsonValue in the cache with the key cache.Insert(keyInt,jsonValue); |
2. JsonObject
JsonObject is a container for unordered name/value pairs where name or key is the name of the attribute and value can be any of the primitive data types. You can parse a whole string containing the JSON data and populate a JsonObject from it. Similarly, a custom object can also be retrieved as a JsonObject and vice versa. The example below shows the creation of a JsonObject with attributes and their values and then adding it to the cache. It then shows further operations on the JsonObject such as removing a particular attribute.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
string key = "jsonKey"; // Create a new JsonObject with the attributes and insert in the cache JsonObject jsonProduct = new JsonObject(); jsonProduct.AddAttribute("ProductID", 1001); jsonProduct.AddAttribute("ProductName", (JsonValue)"Chai"); cache.Insert(key, jsonProduct); // Retrieve the jsonObject previously added the attribute from jsonObject var jsonProduct2 = cache.Get<JsonObject>(key); // Remove the attribute from jsonObject without changing the entire object bool result = jsonProduct2.RemoveAttribute("UnitPrice"); cache.Insert(key, jsonProduct2); |
3. JsonArray
JsonArray is a collection of items and represents JArray in NCache’s domain. Just like JsonObject, you can specify any value or object derived from JsonValueBase. You can add, retrieve or even remove values from a JsonArray at any specified index.
1 2 3 4 |
string jsonProductIds = " ['ProductIDs', { 'ProductID' : 1001 }, { 'ProductID' : 1002 }, { 'ProductID' : 1003 } ]"; // Create a JsonArray with from the JSON document provided var jsonArray = new JsonArray(jsonProductIds); |
4. JsonNull
This class represents null value in JSON standards. The given example shows null value for an attribute of the JsonObject. On further retrieving the attribute with the null value it throws an exception.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Create a new JsonObject with attributes and insert in the cache var jsonProduct = new JsonObject(); jsonProduct.AddAttribute("ProductID", product.ProductID); jsonProduct.AddAttribute("ProductName", (JsonValue)product.ProductName); jsonObject.AddAttribute("Category", null); cache.Insert(key, jsonProduct); // Retrieve the same jsonObject previously created var jsonProduct2 = cache.Get<JsonObject>(key); var productCategory = jsonObject.GetAttributeValue("Cateogry"); // Check if the attribute value is null if(category.DataType == Runtime.Enum.JsonDataType.Null) { // Throw category null Exception } |
NCache Details Cache Data as JSON Docs JSON Serialization
Indexing JSON Documents in NCache
If your cache is a JSON store, you can index your data using either of the following:
- Groups: Items in a cache having a relation between them or falling under the similar category can be grouped in NCache using NCache “Groups” feature. Using Groups, you can logically partition your data for better efficiency.
- Tags: Tags are string-based identifiers, associated with your data. Using Tags, you can associate keywords(s) with your cache items which are then helpful for performing various cache operations on your data using those keywords.
- Named Tags: Named Tags is a feature provided by NCache which is an enhanced form of Tags. They associate particular information with the items in the form of key-value pair at runtime.
JSON documents are added in the cache with these identifiers and NCache indexes the data based on these identifiers. You can later use queries provided by NCache to perform operations on it. The example below shows adding a JSON document in the cache with named tags associated with it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
string jsonString = "{'ProductID' : 1001, 'ProductName' : 'Chai', 'Category': 'Beverages', 'UnitPrice' : 500, 'UnitsInStock' : 2000 }"; // Populate an instance of the JsonObject by passing the string var jsonProduct = new JsonObject(jsonString); string key = $"Products:{product.ProductID}"; var item = new CacheItem(jsonProduct); var productNamedTag = new NamedTagsDictionary(); // Add NamedTag 'Discount' to the dictionary with the value productNamedTag.Add("Discount", 0.5); item.NamedTags = productNamedTag; // Add CacheItem with the NamedTag associated cache.Insert(key, item); |
Searching JSON Documents with SQL in NCache
NCache provides with SQL like queries for retrieving data as well as removing it. You can use queries on the indexed data to fetch the JSON data in any of the formats provided by NCache.
The given example shows querying the data indexed in the above example which is a JSON document added with named tags. The query retrieves all the JsonObjects from the cache with the discount value of 0.5.
1 2 3 4 5 6 7 |
// Create a query for fetching item with NamedTag string query = "Select * FROM Alachisoft.NCache.Runtime.JSON.JsonArray WHERE Discount = ?"; QueryCommand queryCommand = new QueryCommand(query); queryCommand.Parameters.Add("Discount", 0.5); var queryResult = cache.SearchService.ExecuteReader(queryCommand); // QueryResult contains all the keys and metadata of result |
Persisting JSON Documents
NCache has a number of server-side features for performing direct operations on your master data source. These features provide the flexibility of reading or writing data from and to the master data source as well as pre-loading the data in the cache. One of these features called Backing Source provides you with the ease of:
- Read-Through: Read through fetches data from the data source in case it is not present in the cache store.
- Write-Through:Write-through updates data source (any write operation) after updating the cache store.
NCache calls a provider which is written by you, with your custom logic to load data from the master data source or write data to your master data source. The providers are then deployed using NCache Web Manager to use Read-Through/Write-Through.
For the JSON based master data sources such as Cosmos DB, there is an added benefit of using JSON data in the cache. Unlike .NET, for JSON you can write a generic provider for all your applications in JSON to be deployed on your cache to directly load data from the database. You can achieve higher persistence by using these generic providers as JSON is platform independent. .NET requires you to write a different provider for each of your application as the data needs to be serialized and then deserialized. When your cache and your database are both JSON stores, these features provide you with a very high-level persistence increasing your application performance. Given below is a code showing how write-through works with JSON.
1 2 3 4 5 6 7 8 9 10 11 12 |
string jsonString = "{ 'ProductID' : 1001, 'ProductName' : 'Chai', 'Category': 'Beverages', 'UnitPrice' : 500, 'UnitsInStock' : 2000 }"; // Populate an instance of the JsonObject by passing the string var jsonProduct = new JsonObject(jsonString); string key = $"Products:{product.ProductID}"; // Enable write through for the cacheItem created var writeThruOptions = new WriteThruOptions(); writeThruOptions.Mode = WriteMode.WriteThru; // Add the item in the cache with WriteThru enabled CacheItemVersion itemVersion = cache.Insert(key, cacheItem, writeThruOptions); |
You can get a complete guide to NCache’s server-side features.
JSON Serialization of .NET and Java Objects
In NCache, all the data added in the cache is serialized. The serialization can either be binary or JSON. It is a platform independent language and has a lot of edge for being supported widely. Almost all programming languages support serializing and deserializing JSON in their standard libraries. NCache takes your custom object, JSON serializes it by converting it into JSON and then deserializes it back to the custom object.
JSON serializing your data in NCache allows you a lot of flexibility as it uses JSON.NET so it is extremely portable with multiple languages and deserializes the data according to the user requirement. It requires no code change and provides you with an ease to specify the non-serializable attributes.
Look at the example below for data in .NET and it’s JSON’s equivalent.
.NET | JSON |
Product product = new Product(); |
{ |
Data sharing is one of the central benefits of JSON serializing your data. JSON being fairly easy, understandable and having no complex libraries lets you provide the type in which data needs to be deserialized. It has a very flexible schema for serialization given that the attributes are the same when deserializing. Not just that, it even lets you map two different versions of the same class serialized with JSON. You can JSON serialize your data from a .NET class and a Java application can access the serialized data with the name attributes. Figure 1 illustrates how data is shared between .NET and Java applications using JSON serialization in the cache.
Conclusion
This brings us to the end of our blog which shows the significance of NCache as a JSON store. NCache is an in-memory distributed cache which lets you use JSON documents in the cache. It allows you to keep the persistent data in the cache with added benefits of JSON serialization and data sharing between .NET and Java application.