by cheptsov

cheptsov / kotlin-nosql

NoSQL database query and access library for Kotlin

205 Stars 30 Forks Last release: Not found 214 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Kotlin NoSQL

Kotlin NoSQL is a reactive and type-safe DSL for working with NoSQL databases.


Under development (POC). The following NoSQL databases are supported now:

Feedback is welcome.


To use it with Maven insert the following code in your pom.xml file:



To use it with Gradle insert the following code in your build.gradle:

repositories {
    maven {
        url "http://repository.jetbrains.com/kotlin-nosql"

dependencies { compile 'org.jetbrains.kotlin:kotlin-nosql-mongodb:0.1-SNAPSHOT' }

Getting Started

Demo: http://www.youtube.com/watch?v=80xgl3KThvM


Define a schema

object Comments: DocumentSchema("comments", Comment::class) {
    val discussionId = id("discussion_id", Discussions)
    val slug = string("slug")
    val fullSlug = string("full_slug")
    val posted = dateTime("posted")
    val text = string("text")

val AuthorInfo = AuthorInfoColumn()

class AuthorInfoColumn() : Column<authorinfo comments>("author", AuthorInfo::class) {
    val authorId = id("id", Authors)
    val name = string("name")


class Comment(val discussionId: Id, val slug: String, val fullSlug: String, posted: DateTime, text: String, authorInfo: AuthorInfo) { val id: Id? = null }

class AuthorInfo(val authorId: Id, val name: String)

Define a database

val db = MongoDB(database = "test", schemas = arrayOf(Comments), action = CreateDrop(onCreate = {
    // ...

db.withSession { // ... }

Insert a document

Comments.insert(Comment(DiscussionId, slug, fullSlug, posted, text, AuthorInfo(author.id, author.name)))

Get a document by id

val comment = Comments.find { id.equal(commentId) }.single()

Get a list of documents by a filter expression

val comments = Comments.find { authorInfo.id.equal(authorId) }.sortBy { posted }.skip(10).take(5).toList()

Get selected fields by document id

val authorInfo = Comments.find { id.equal(commentId) }.projection { authorInfo }.single()

Get selected fields by a filter expression

Comments.find { discussionId.equal(id) }).projection { slug + fullSlug + posted + text + authorInfo }.forEach {
    val (slug, fullSlug, posted, text, authorInfo) = it

Update selected fields by document id

Comments.find { id.equal(commentId) }.projection { posted }.update(newDate)
Comments.find { id.equal(commentId) }.projection { posted + text }.update(newDate, newText)


Define a base schema

open class ProductSchema(javaClass: Class, discriminator: String) : DocumentSchema("products",
            discriminator = Discriminator(string("type"), discriminator)) {
    val sku = string("sku")
    val title = string("title")
    val description = string("description")
    val asin = string("asin")

val Shipping = ShippingColumn<s>()
val Pricing = PricingColumn<s>()

inner class ShippingColumn<s : documentschema>&gt;() : Column<shipping s>("shipping", Shipping::class) {
    val weight = integer<s>("weight")
    val dimensions = DimensionsColumn<s>()

inner class DimensionsColumn<s : documentschema>&gt;() : Column<dimensions s>("dimensions", Dimensions::class) {
    val width = integer<s>("width")
    val height = integer<s>("height")
    val depth = integer<s>("depth")

inner class PricingColumn<s : documentschema>&gt;() : Column<pricing s>("pricing", Pricing::class) {
    val list = integer<s>("list")
    val retail = integer<s>("retail")
    val savings = integer<s>("savings")
    val ptcSavings = integer<s>("pct_savings")


object Products : ProductSchema(Product::class, "")

abstract class Product(val id: Id? = null, val sku: String, val title: String, val description: String, val asin: String, val shipping: Shipping, val pricing: Pricing) { val id: Id? = null }

class Shipping(val weight: Int, val dimensions: Dimensions)

class Dimensions(val width: Int, val height: Int, val depth: Int)

class Pricing(val list: Int, val retail: Int, val savings: Int, val pctSavings: Int)

Define an inherited schema

object Albums : ProductSchema(Album::class, discriminator = "Audio Album") {
    val details = DetailsColumn()

class DetailsColumn() : Column<details albums>("details", Details::class) {
    val title = string("title")
    val artistId = id("artistId", Artists)
    val genre = setOfString("genre")

    val tracks = TracksColumn()

class TracksColumn() : ListColumn<track albums>("tracks", Track::class) {
    val title = string("title")
    val duration = integer("duration")


class Album(sku: String, title: String, description: String, asin: String, shipping: Shipping, pricing: Pricing, val details: Details) : Product(sku, title, description, asin, shipping, pricing)

class Details(val title: String, val artistId: Id, val genre: Set, val tracks: List)

Insert a document

val productId = Products.insert(Album(sku = "00e8da9b", title = "A Love Supreme", description = "by John Coltrane",
    asin = "B0000A118M", shipping = Shipping(weight = 6, dimensions = Dimensions(10, 10, 1)),
    pricing = Pricing(list = 1200, retail = 1100, savings = 100, pctSavings = 8),
    details = Details(title = "A Love Supreme [Original Recording Reissued]",
            artistId = artistId, genre = setOf("Jazz", "General"),
            tracks = listOf(Track("A Love Supreme Part I: Acknowledgement", 100),
                    Track("A Love Supreme Part II: Resolution", 200),
                    Track("A Love Supreme, Part III: Pursuance", 300)))))

Access documents via an abstract schema

for (product in Products.find { id.equal(productId) }) {
    if (product is Album) {

Access documents via an inherited schema

val album = Albums.find { details.artistId.equal(artistId) }.single()


We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.