Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Potassium Nitrite: A NoSQL Persistent Document Store for Kotlin

DZone's Guide to

Potassium Nitrite: A NoSQL Persistent Document Store for Kotlin

Learn how Potassium Nitrite aims to streamline the usage of Nitrite with Kotlin by leveraging its language features, extension functions, builders, and infix functions.

· Database Zone ·
Free Resource

RavenDB vs MongoDB: Which is Better? This White Paper compares the two leading NoSQL Document Databases on 9 features to find out which is the best solution for your next project.  

Potassium Nitrite (KNO2) is a Kotlin extension of the Nitrite database. It aims to streamline the usage of Nitrite with Kotlin by leveraging its language features like extension functions, builders, infix functions, etc. Here is the GitHub page for the library.

How to Install

To use Potassium Nitrite in any Kotlin application, just add the below dependency:

Maven:

<dependency>
    <groupId>org.dizitart</groupId>
    <artifactId>potassium-nitrite</artifactId>
    <version>2.1.0</version>
</dependency>

Gradle:

compile 'org.dizitart:potassium-nitrite:2.1.0'

Usage

Initialize Database

The database can be initialized using the builder method nitrite:

// without credentials
val db = nitrite {
    file = File(fileName)       // or, path = fileName
    autoCommitBufferSize = 2048
    compress = true
    autoCompact = false
}

// with credentials
val db = nitrite("userId", "password") {
    file = File(fileName)       // or, path = fileName
    autoCommitBufferSize = 2048
    compress = true
    autoCompact = false
}

Collection/repository:

// add import statement
import org.dizitart.kno2.*

// Initialize a Nitrite Collection
val collection = db.getCollection("test") {
    insert(documentOf("a" to 1),
            documentOf("a" to 2),
            documentOf("a" to 3),
            documentOf("a" to 4),
            documentOf("a" to 5))

    val cursor = find(limit(0, 2))
}

// Initialize an Object Repository
val repository = db.getRepository<Employee> {
    insert(Employee(1, "red"), Employee(2, "yellow"))
}

Document Builder

The library has some builder methods to create documents:

// add import statement
import org.dizitart.kno2.*

// create empty document
val doc = emptyDocument()
val doc = documentOf()

// create a document with one pair
val doc = documentOf("a" to 1)

// create a document with more pairs
val doc = documentOf("a" to 1, "b" to 2, "c" to 3)

Filters

This library has some convenient infix functions for creating search filters.

Document filter:

// add import statement
import org.dizitart.kno2.filters.*

// equivalent to eq("a", 1)
val cursor = find("a" eq 1)

// equivalent to gt("a", 1)
val cursor = find("a" gt 1)

// equivalent to gte("a", 1)
val cursor = find("a" gte 1)

// equivalent to lt("a", 1)
val cursor = find("a" lt 1)

// equivalent to lte("a", 1)
val cursor = find("a" lte 1)

// equivalent to `in`("a", arrayOf(1, 2, 5))
val cursor = find("a" within arrayOf(1, 2, 5))

// equivalent to `in`("a", 1..5)
val cursor = find("a" within 1..5)

// equivalent to `in`("a", listOf(1, 2, 3))
val cursor = find("a" within listOf(1, 2, 3))

// equivalent to elemMatch("a", `in`("$", 3..5))
val cursor = find("a" elemMatch ("$" within 3..5))

// equivalent to text("a", "*ipsum")
val cursor = find("a" text "*ipsum")

// equivalent to regex("a", "[a-z]+")
val cursor = find("a" regex "[a-z]+")

// equivalent to and(eq("a", 1), gt("b", 2))
val cursor = find(("a" eq 1) and ("b" gt 2))

// equivalent to or(eq("a", 1), gt("b", 2))
val cursor = find(("a" eq 1) or ("b" gt 2))

// equivalent to not("a" within 1..5))
val cursor = find(!("a" within 1..5))

Object Filters

Infix functions for object filters only apply for simple properties of Kotlin classes:

// add import statement
import org.dizitart.kno2.filters.*

@Indices(Index(value = "text", type = IndexType.Fulltext))
data class TestData(@Id val id: Int, val text: String, val list: List<ListData> = listOf())

class ListData(val name: String, val score: Int)

// equivalent to eq("id", 1)
val cursor = find(TestData::id eq 1)

// equivalent to gt("id", 1)
val cursor = find(TestData::id gt 1)

// equivalent to gte("id", 1)
val cursor = find(TestData::id gte 1)

// equivalent to lt("id", 1)
val cursor = find(TestData::id lt 1)

// equivalent to lte("id", 1)
val cursor = find(TestData::id lte 1)

// equivalent to `in`("id", 1..2)
val cursor = find(TestData::id within 1..2)

// equivalent to elemMatch("list", eq("score", 4))
val cursor = find(TestData::list elemMatch (ListData::score eq 4))

// equivalent to text("text", "*u*")
val cursor = find(TestData::text text "*u*")

// equivalent to regex("text", "[0-9]+")
val cursor = find(TestData::text regex "[0-9]+")

// equivalent to and(eq("id", 1), text("text", "12345"))
val cursor = find((TestData::id eq 1) and (TestData::text text "12345"))

// equivalent to or(eq("id", 1), text("text", "12345"))
val cursor = find((TestData::id eq 1) or (TestData::text text "12345"))

// equivalent to not(lt("id", 1))
val cursor = find(!(TestData::id lt 1))

Kotlin Data Class

The library has built-in support for Kotlin data classes via the jackson-kotlin module. This module is already registered to the default Jackson mapper so that the user does not have to deal with it explicitly.

Further Reading

To learn further capabilities of Nitrite, consult the documentation. There are also two articles here and here on Nitrite that are very helpful to get you started.

Get comfortable using NoSQL in a free, self-directed learning course provided by RavenDB. Learn to create fully-functional real-world programs on NoSQL Databases. Register today.

Topics:
database ,nosql ,nitrite ,kotlin ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}