Introduction to Java API in NoSQL Database - NosDB

NosDB is an extremely fast, highly scalable .NET based NoSQL solution which can readily accommodate colossal amounts of unstructured data. It applies stable distribution strategies to maintain the integrity of the data, while simultaneously providing its users with a fault tolerant system at all times.

In two previous articles, we discussed NosDB's .NET client API and server-side code handling in detail. In addition to these features, NosDB officially supports a JAVA client. It's mandatory for all clients, other than the .NET ones, to have a running distributor service dedicated to the distribution of client operations across existing database servers. Kindly ensure that your service is up and running before beginning your work with the JAVA client (for help regarding the distributor service, refer to the NosDB Admin guide).

This article presents a brief walk through to quickly get started with the basics of the JAVA API.

The Basics

To begin working with NosDB using the JAVA client, your application first needs to connect to a database using a connection string.

A connection string consists of:

  • A data source address (IP and Port),

  • Name of the concerned database,

  • The local instance value which indicates if the database is stand-alone or clustered,

  • The Distributor service address (IP and Port) is required for the JAVA client,

  • Security authentication (Username and password) is required because the default authentication mode is not supported for clients other than .NET.

In this example, we want to connect to a stand-alone database, so the Local Instance value is set to true:


// connection string
String conn = "Data Source = 192.168.8.101; Port = 9950; Database = northwind; Local Instance = true; Distributor Address = 192.168.8.101; Distributor Port = 9970; User Id = admin; password = alachisoft;";

// initialize database
Database db = NosDB.getDatabase(conn);

Next, we need a collection within a database. Collections are kindred to tables in a traditional database; but unlike a table, a collection stores data in the form of JSON which is schema-less. While working with a NosDB collection, you can use both custom objects and JSON documents to manipulate your data. The client, however, is designed to convert your data to the JSON format either way.

In the examples that follow, we will largely be working with JAVA objects. It can, however, work equally well with JSON documents.

The sample JAVA class used in this tutorial is:


public class Product {

    @SerializedName ("_key")
    public String ProductID;
    
    public String ProductName;
}

Note that in the class above, 'ProductID' is labeled as the 'key' so when you insert a document into a collection using an object of the 'Product' class, NosDB will automatically set it as the key for your inserted document.

We form an instance of the "Products" collection (assuming that it already exists) by passing the name of the collection as a string, as shown in the code snippet below:


// Create a collection instance
DBCollection collection = db.getCollection("Products", Product.class);

You can also initialize a collection using the JSON documents following the pattern below:

DBCollection  collection = db.getCollection("Products"); 

All the code snippets that follow hereon will be working with the "Products" collection.

Having done the above, we are ready to work with the data in the "Products" collection. The kinds of APIs supported by NosDB's JAVA client can be broadly categorized into the following types:

  • Basic Operations

  • Bulk Operations

  • Structured Query Language (SQL)

JAVA Client: Basic Operations

To work with single JSON documents, NosDB offers the following basic operations:

  • Insert document

  • Get document

  • Update document

  • Delete document

INSERT DOCUMENT:

The insertDocument() API can be used to insert a single document into the database. You can specify an attribute to be set as the key. If, however, no key was defined at the time of insertion, NosDB will automatically generate one and store the document against it.

The code snippet below shows how to insert a single custom object into the "Products" collection:

Product product = new Product();
product.ProductID = "12";
product.ProductName = "Coke";
        
collection.insertDocument(product);

GET DOCUMENT:

To retrieve a document from the database, you need to provide a key. Since NosDB can also be considered a key-value store, the object against the key will be searched in the collection and returned if found.

The getDocument() API fetches a document from the database. The following example demonstrates how to retrieve an existing item from the "Products" collection:


Product result = collection.getDocument("12");
                
// perform operations

UPDATE DOCUMENT:

To replace a single document in the database, you can use the updateDocument() method and specify the key of the document along with the required update. If, however, the targeted key is not present in the collection, an OperationFailedException is thrown.

The example below replaces an existing document in the 'Products' collection:

Product product = new Product();
product.ProductID = "12";
product.ProductName = "Pepsi";
        
collection.updateDocument(product);

DELETE DOCUMENT:

To delete a document from the database, you provide a string-based key to the deleteDocument() API as follows:

// delete document
collection.deleteDocument("12");

JAVA Client: Bulk Operations

NosDB supports manipulating bulk data, so when you send a request that consists of multiple documents, which may or may not reside on the same shard, NosDB directs the documents to the parent shards from the client end. Moreover, results are compiled on each shard individually before sending the call back to the client. These features reduce bandwidth usage multifold. NosDB is therefore efficient in managing bulk operations for large amounts of data.

As with basic operations, NosDB has four types of bulk operations:

  • Insert documents

  • Get documents

  • Update documents

  • Delete documents

INSERT DOCUMENTS:

For bulk insert, the insertDocuments() method is available which takes a collection of documents as input and inserts them into the database. If any of the documents in the list fail to insert, they are returned in an array list.

The example below inserts two documents into the "Products" collection:

Product product1 = new Product();
product1.ProductID = "12";
product1.ProductName = "Coke";
        
Product product2 = new Product();
product2.ProductID = "13";
product2.ProductName = "Tea";
        
java.util.Collection products = new java.util.ArrayList<>();
        
products.add(product1);
products.add(product2);
        
java.util.ArrayList failedDocs = collection.insertDocuments(products);

GET DOCUMENTS:

To fetch documents in bulk, NosDB has a getDocuments() API which either takes a list of keys or a specific criteria as input and returns a DBCollectionReader which can be enumerated for the results.

The following example fetches documents against the specified set of keys (if found) from the "Products" collection:

// Specify a list of keys
java.util.Collection docKeys = new java.util.ArrayList<>();
        
docKeys.add("12");
docKeys.add("13"); 
        
DBCollectionReader reader = collection.getDocuments(docKeys);
        
while(reader.readNext())
{
    Product result = reader.getObject();
    // perform operations
}

UPDATE DOCUMENTS:

The updateDocuments() API replaces a list of documents against a set of unchanged keys. If a key(s) is not found in the collection, it is returned in a list of failed documents.

The example below replaces two documents in the 'Products' collection:

Product product1 = new Product();
product1.ProductID = "12";
product1.ProductName = "Pepsi";
        
Product product2 = new Product();
product2.ProductID = "13";
product2.ProductName = "Coffee";
        
java.util.Collection products = new java.util.ArrayList<>();
        
products.add(product1);
products.add(product2);
        
java.util.ArrayList failedDocs = collection.updateDocuments(products);

DELETE DOCUMENTS:

The deleteDocuments() API is used to delete multiple documents from a collection as demonstrated below:

// Specify a list of keys
java.util.Collection docKeys = new java.util.ArrayList<>();
        
docKeys.add("12");
docKeys.add("13"); 
        
// delete the documents using the following API
java.util.ArrayList failedDocs = collection.deleteDocuments(docKeys);

JAVA Client: Structured Query Language (SQL)

SQL, or 'Structured Query Language', is widely used in databases to manipulate data. Since NosDB supports arrays as field values, the columns of a collection can be multi-valued, unlike traditional databases; therefore, it works with the embedded data model as well. NosDB has extended the existing SQL structure to accommodate the additional data flexibility of its JSON schema.

The JAVA client of NosDB supports Data Manipulation Language (DML) through which you can query your data. The makers of NosDB recommend using queries to operate on NosDB databases. Therefore, NosDB uses expanded SQL queries to effectively accommodate JSON documents.

The following describes SQL support offered in NosDB. (For more in-depth knowledge, please refer to the SQL cheat sheet):

ExecuteReader():

This method is used for SELECT statements to retrieve documents from the database:


// define a query
String query = "SELECT ProductName FROM Products WHERE ProductID = '12'";
DBCollectionReader reader = db.executeReader(query);
        
while (reader.readNext())
{
    Product product = reader.getObject();
    // perform operations
}

ExecuteNonQuery():

This method is used to modify the collections of a database (INSERT, UPDATE, and DELETE). ExecuteNonQuery also supports Document Definition Language (DDL) and Document Control Language (DCL). But this example sticks to DML. The supported queries are also shown on the SQL Cheat Sheet.

The code snippet below shows how to insert data into the collection via querying:


// define a query
String query = "INSERT into Products (ProductID, Name) VALUES ('14', 'Apple Juice')";
        
// execute the query using the executeNonQuery API
long rowsAffected = db.executeNonQuery(query);

ExecuteScalar():

For situations where only the first result from the set is required or if the expected query result is a single value, the ExecuteScalar() method is used.

The example below demonstrates the use of aggregate querying in NosDB:


// Define a query
String query = "SELECT Count(*) FROM Products WHERE Name = 'Coke'";
        
// execute the query using the executeScalar API
Object count = db.executeScalar(query);

This marks the end of this quick tutorial on JAVA clients in NosDB. For further guidance and detailed documentation, visit NosDB JAVA API reference.