Since Kinetica isn't a standard RDBMS, we have created this simple guide to get you started with your development efforts.
We suggest using Maven as the build tool for your Java project. To use the
Kinetica Java API, you must add our Nexus repository and the
Kinetica Java API dependency and replace KINETICA_VERSION
with the version
number that matches that of the targeted Kinetica database, as shown below:
<properties>
<gpudb-api.version>KINETICA_VERSION</gpudb-api.version>
</properties>
.
.
.
<repository>
<id>releases</id>
<name>GPUdb Releases</name>
<url>http://files.kinetica.com/nexus/content/repositories/releases/</url>
</repository>
.
.
.
<dependency>
<groupId>com.gpudb</groupId>
<artifactId>gpudb-api</artifactId>
<version>${gpudb-api.version}</version>
</dependency>
Note:Use the Kinetica version number you are developing against for the gpudb-api.version
The GPUdb
object provides access to your Kinetica instance. To interact
with Kinetica, you must create a new object of this class, passing the URL of
the instance you are connecting to:
try {
GPUdb gpudb = new GPUdb("http://localhost:9191");
}
catch (GPUdbException ex) {
ex.printStackTrace();
}
Tables in Kinetica are similar to tables in other databases--they have a
user-provided name and definition. The Kinetica Java API provides a base
class, RecordObject
, to facilitate the creation of a type definition that
will be used for most table operations. Below is an example record object type
that will be used throughout the examples on this page:
import com.gpudb.ColumnProperty;
import com.gpudb.RecordObject;
public class WeatherRecord extends RecordObject
{
/** unique identifier of tweet */
@RecordObject.Column(order = 0, properties = { ColumnProperty.DATA })
public long timestamp;
/** longitude of city */
@RecordObject.Column(order = 1)
public float x;
/** latitude of city */
@RecordObject.Column(order = 2)
public float y;
/** city name */
@RecordObject.Column(order = 3)
public String cityName;
/** country */
@RecordObject.Column(order = 4)
public String country;
/** region */
@RecordObject.Column(order = 5)
public String region;
/** temperature */
@RecordObject.Column(order = 6)
public float temperature;
/** weather conditions */
@RecordObject.Column(order = 7)
public String weatherConditions;
}
Note:Although a constructor is not required, if the class does have any constructors, it must have a constructor with no parameters. Other constructors can be added.
After defining the record object class for the table, we create a type for the table definition and add that type to Kinetica. At this point, Kinetica knows about this type and can perform operations with it. The code below shows a type being created within Kinetica from the class above, and a table created from that type:
String tableName = "WeatherTable";
try {
String typeId = RecordObject.createType(WeatherRecord.class, gpudb);
gpudb.createTable(tableName, typeId, null);
}
catch (GPUdbException e) {
if (e.getMessage().contains("already exists")) {
System.out.println("Table " + tableName + " already exists");
}
}
To write to a table, first create a new object of the table type:
WeatherRecord record = new WeatherRecord();
record.timestamp = System.currentTimeMillis();
.
.
.
Next, create a BulkInserter and insert the record(s). When you are done inserting records, make sure to call BulkInserter flush method to ensure all records get written:
try {
BulkInserter<WeatherRecord> bulkInserter = new BulkInserter<>(gpudb, tableName, record.getType(), 1, null);
bulkInserter.insert(record);
bulkInserter.flush();
}
catch (GPUdbException ex) {
ex.printStackTrace();
}
Since Kinetica is designed to handle big data, records are retrieved in
chunks. For example, to get the first 1000 records from the Weather
table:
try {
GetRecordsResponse<WeatherRecord> response;
response = gpudb.getRecords(WeatherRecord.class, tableName, 0, 1000, null);
List<WeatherRecord> responseList = response.getData();
for(WeatherRecord t : responseList) {
System.out.println(t.toString());
}
}
catch (GPUdbException ex) {
ex.printStackTrace();
}
To read all records in a table, you would retrieve chunks of records until all of them have been read. An example of this is:
public void read(String tableName) {
int MAX_READ = 1000;
try {
long start = 0;
Map<String,String> options = new HashMap<>();
options.put(ShowTableRequest.Options.GET_SIZES, ShowTableRequest.Options.TRUE);
ShowTableRequest showTableRequest = new ShowTableRequest();
showTableRequest.setTableName(tableName);
showTableRequest.setOptions(options);
ShowTableResponse tableResponse = gpudb.showTable(showTableRequest);
long size = tableResponse.getTotalSize();
//page reading by MAX_READ records
for(long i = 0; i < size; i += MAX_READ) {
GetRecordsResponse<T> response = gpudb.getRecords(this.typeParameterClass, tableName, start, MAX_READ, null);
List<T> responseList = response.getData();
for(T t : responseList) {
System.out.println(t.toString());
}
start += MAX_READ;
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
Kinetica provides a general purpose filter function and many highly optimized
filter functions. These filters create new, usually temporary, views
containing the filtered data. The general purpose filter method works similarly
to the SQL SELECT ... WHERE ...
query. Using our weather example, let's
say you want to filter on records where the temperature is over 70. The
following code will create a new view called Over70
containing all the
records matching our filter expression:
long numResults = 0;
String filterResults = "Over70";
try {
String expression = "temperature > 70.0";
FilterResponse resp = gpudb.filter(tableName, filterResults, expression, null);
numResults = resp.getCount();
}
catch (GPUdbException ex) {
ex.printStackTrace();
}
Records from this new table are retrieved in the same manner as described in Reading Records from a Table above.
For more details on filtering expressions, see concepts.
To delete records from a table, you would use filter expressions to identify the records to delete. The delete method allows you to specify multiple filter expressions, so it takes a list of expressions, rather than a single string.
Continuing our example, let's delete all records where the temperature is below 50:
ArrayList<String> deleteExpressions = new ArrayList<>();
deleteExpressions.add("temperature < 50.0");
try{
gpudb.deleteRecords(tableName, deleteExpressions, null);
}
catch (GPUdbException ex) {
ex.printStackTrace();
}