{"id":34997358,"url":"https://github.com/mnbjhu/kotlinredisgraph","last_synced_at":"2026-04-13T12:01:26.741Z","repository":{"id":50379069,"uuid":"517731520","full_name":"mnbjhu/KotlinRedisGraph","owner":"mnbjhu","description":"A small Cypher DSL for interacting with Redis databases in Kotlin","archived":false,"fork":false,"pushed_at":"2022-11-17T18:38:47.000Z","size":398,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-09T04:33:24.249Z","etag":null,"topics":["cypher","cypher-query-language","dsl","jedis","kotlin","ktor","redis","redis-client","redisgraph","spring-boot","typesafe"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnbjhu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-25T16:01:04.000Z","updated_at":"2023-02-06T20:30:23.000Z","dependencies_parsed_at":"2023-01-21T22:00:26.690Z","dependency_job_id":null,"html_url":"https://github.com/mnbjhu/KotlinRedisGraph","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/mnbjhu/KotlinRedisGraph","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnbjhu%2FKotlinRedisGraph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnbjhu%2FKotlinRedisGraph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnbjhu%2FKotlinRedisGraph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnbjhu%2FKotlinRedisGraph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnbjhu","download_url":"https://codeload.github.com/mnbjhu/KotlinRedisGraph/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnbjhu%2FKotlinRedisGraph/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31751705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cypher","cypher-query-language","dsl","jedis","kotlin","ktor","redis","redis-client","redisgraph","spring-boot","typesafe"],"created_at":"2025-12-27T02:43:04.474Z","updated_at":"2026-04-13T12:01:26.735Z","avatar_url":"https://github.com/mnbjhu.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redis For Kotlin \n[![](https://jitpack.io/v/mnbjhu/KotlinRedisGraph.svg)](https://jitpack.io/#mnbjhu/KotlinRedisGraph)\n## Overview\nInspired by Kotlin Exposed, this library aims to provide a type-safe DSL for interacting with Redis Graph to Kotlin.\n#### Kotlin Redis Graph\n* Construct schemas for nodes\n* Create, read, update and delete nodes and relationships\n* Perform path queries\n## Setup\n### Gradle\n**Step 1.** Add the JitPack repository to your build.gradle\n```groovy\nallprojects {\n    repositories {\n        /* ... */\n        maven { url \"https://jitpack.io\" }\n    }\n}\n```\n**Step 2.** Add the dependency\n```groovy\ndependencies {\n  // Core DSL\n    implementation \"com.github.mnbjhu.KotlinRedisGraph:core:$kotlinRedisVersion\"\n  // Annotations\n    kapt \"com.github.mnbjhu.KotlinRedisGraph:annotations:$kotlinRedisVersion\"\n}\n```\n### Gradle Kotlin DSL\n**Step 1.** Add the JitPack repository to your build.gradle.kts\n```kotlin\nrepositories {\n    mavenCentral()\n    maven(\"https://jitpack.io\")\n}\n```\n**Step 2.** Add the dependency\n```kotlin\ndependencies {\n  // Core DSL\n  implementation(\"com.github.mnbjhu.KotlinRedisGraph:core:$kotlinRedisVersion\")\n  // Annotations\n  implementation(\"com.github.mnbjhu.KotlinRedisGraph:annotations:$kotlinRedisVersion\")\n}\n```\n## Basic Usage\n### Connect To Redis\nTo start using Redis Graph you need to create a new instance of the RedisGraph class with a graph name, host address and an option port (default is 6379).\n```kotlin\nimport uk.gibby.redis.core.RedisGraph\n\nval moviesGraph = RedisGraph(\n    name = \"movies\",\n    host = \"raspberrypi.local\",\n)\n```\n### Define A Schema\nNode types and their relationships are defined by a schema. To create a node type, create a class which:\n\n```kotlin\nimport uk.gibby.redis.core.UnitNode\nimport uk.gibby.redis.core.UnitRelation\n\nclass ActorNode: UnitNode(){\n    val name by string()\n    val actorId by long()\n    val actedIn = relates(ActedInRelation::class)\n}\nclass MovieNode : UnitNode(){\n    val title by string()\n    val releaseYear by long()\n    val movieId by long()\n}\nclass ActedInRelation: UnitRelation\u003cActorNode, MovieNode\u003e(){\n    val role by string()\n}\n```\n\n#### Experimental CodeGen\nThis will generate the same as the above but will instead create instances of RedisRelation\u0026lt;ActedIn\u0026gt;, RedisNode\u0026lt;Movie \u0026gt; and RedisNode\u0026lt;Actor\u0026gt; respectively (as appose to UnitNode). This will allow you to return the nodes them self as the defined data classes.\n```kotlin\nimport uk.gibby.redis.annotation.RedisType\nimport uk.gibby.redis.annotation.Node\nimport uk.gibby.redis.annotation.RelatesTo\n\n@RedisType\ndata class ActedIn(val role: String)\n\n@Node\ndata class Movie(val title: String, val releaseYear: Long)\n\n@Node\n@Relates(to = Movie::class, by = \"actedIn\", data = ActedIn::class)\ndata class Actor(val name: String)\n```\nAttributes can be defined on both **RedisClass** and **RedisRelation**. While in either scope, you'll have access to functions for setting the values of the attributes.\n\n**Currently Supported Types Are:**\n\n\u003cins\u003ePrimitives\u003c/ins\u003e\n\n| Type    | Function  |\n|---------|-----------|\n| String  | string()  |\n| Long    | long()    |\n| Double  | double()  |\n| Boolean | boolean() |\n\n\u003cins\u003eArrays\u003c/ins\u003e\n```kotlin\nclass MyNode: UnitNode(){\n    /* ND arrays of any result type are supported */\n    val myArray by array(string())\n    val my2DArray by array(array(string()))\n}\n```\n\u003cins\u003eStructured Types\u003c/ins\u003e\n```kotlin\nimport ...\n/* Defines a type which can be returned */\nclass Vector3Result : StructResult\u003cVector3\u003e() {\n    val x: DoubleResult by double()\n    val y: DoubleResult by double()\n    val z: DoubleResult by double()\n    \n    fun ResultScope.getResult(): Vector3 = Vector3(!x, !y, !z)\n    \n    fun ParamMap.setResult(value: Vector3){\n        x[value.x]\n        y[value.y]\n        z[value.z]\n    }\n}\n/* Defining the attribute will allow you to store the type on a node or relation */\nclass Vector3Attribute : Vector3Result(), Attribute\u003cVector3\u003e\n\nclass MyNode: UnitNode(){\n    val myVector by ::Vector3Attribute\n}\n```\n\n#### Experimental CodeGen Annotation\n```kotlin\n@RedisType\ndata class Vector(val x: Double, val y: Double, val z: Double)\n```\n### Create Nodes\nAfter a node type has been defined as a **RedisClass**, you can create a single instance like so:\n```kotlin\nmoviesGraph.create(::MovieNode) {\n    title[\"Star Wars: Episode V - The Empire Strikes Back\"]\n    releaseYear[1980]\n    movieId[1]\n}\n```\n##### Generated Cypher\n```cypher\nCREATE (:MovieNode{title:'Star Wars: Episode V - The Empire Strikes Back', release_year:1980, movie_id:1})\n```\n(If an attribute is defined in the type but not set on creation, and exception will be thrown)\n  \nYou can also create multiple instances by mapping elements from a list.\n```kotlin\nvar index = 1L\nval actors = listOf(\n    \"Mark Hamill\",\n    \"Harrison Ford\",\n    \"Carrie Fisher\"\n)\nmoviesGraph.create(::ActorNode, actors) {\n    name[it]\n    actorId[index++]\n}\n```\n\n##### Generated Cypher\n```cypher\nCREATE (:ActorNode{name:'Mark Hamill', actor_id:1}), (:ActorNode{name:'Harrison Ford', actor_id:2}), (:ActorNode{name:'Carrie Fisher', actor_id:3})\n```\n### Query Scope\nCurrently, all other functionality is performed with the **query** function which takes a lambda returning a result value.\n#### Example:\nReturns a list of all the movie names in the graph.\n```kotlin\nmoviesGraph.query {\n    match(::MovieNode)\n    movie.title\n}\n```\n### Create Relationships\n```kotlin\nmoviesGraph.query {\n    val (actor, movie) = match(::ActorNode, ::MovieNode)\n    where ((actor.actorId eq 1) and (movie.movieId eq 1))\n    create(actor - { actedIn { role[\"Luke Skywalker\"] } } - movie)\n}\nmoviesGraph.query {\n    val (actor, movie) = match(::ActorNode, ::MovieNode)\n    where ((actor.actorId eq 2) and (movie.movieId eq 1))\n    create(actor - { actedIn{role[\"Han Solo\"]} } - movie)\n}\nmoviesGraph.query {\n    val (actor, movie) = match(::ActorNode, ::MovieNode)\n    where ( (actor.actorId eq 3) and (movie.movieId eq 1) )\n    create(actor - { actedIn{role[\"Princess Leia\"]} } - movie)\n}\n```\n##### Generated Cypher\n```cypher\nMATCH (actor:ActorNode), (movie:MovieNode)\nWHERE (actor.actor_id = 1) AND (movie.movie_id = 1)\nCREATE (actor)-[r:ACTED_IN {role:'Luke Skywalker'}]-\u003e(movie)\n```\nAlternatively you can create the node and edges as a single query:\n```kotlin\ngraph.query {\n    val movie = create(::MovieNode {\n        it[title] = \"Star Wars: Episode V - The Empire Strikes Back\"\n        it[releaseYear] = 1980\n    })\n    create(::ActorNode{ it[name] = \"Mark Hamill\" } - { actedIn { it[role] = \"Luke Skywalker\" } } - movie)\n    create(::ActorNode{ it[name] = \"Harrison Ford\" } - { actedIn{ it[role] = \"Han Solo\" } } - movie)\n    create(::ActorNode{ it[name] = \"Carrie Fisher\" } - { actedIn{ it[role] = \"Princess Leia\" } } - movie)\n}\n```\n### Constructing Queries\nIn this example we search for all movies and return the movie 'title'.\n\nThe same however we also return the 'releaseYear' and the 'movieId':\n```kotlin\nval movies = moviesGraph.query{\n    val movie = match(::MovieNode)\n    movie.title\n}\nmovies `should contain` \"Star Wars: Episode V - The Empire Strikes Back\"\n```\n##### Generated Cypher\n```cypher\nMATCH (movie:MovieNode)\nRETURN movie.title\n```\n\nWhen using the @Node annotation we can return the movie node itself\n```kotlin\n@Node\ndata class Movie(val title: String, val releaseYear: Long, val movieId: Long)\n\nval (title, releaseYear, id) = moviesGraph.query {\n    val movie = match(::MovieNode)\n    movie\n}.first()\n\ntitle as String `should be equal to` \"Star Wars: Episode V - The Empire Strikes Back\"\nreleaseYear as Long `should be equal to` 1980\nid as Long `should be equal to` 1\n```\n##### Generated Cypher\n```cypher\nMATCH (movie:MovieNode)\nRETURN movie.title, movie.release_year, movie.movie_id\n```\nHere we:\n* Search for an actor and a movie where the actor acted in the movie.\n* Filter by movieId = 1\n* And return the actor name and movie title\n```kotlin\nval actedInMovies = moviesGraph.query {\n    val (actor, _, movie) = match(::ActorNode - { actedIn }  - ::MovieNode)\n    where (movie.movieId eq 1)\n    orderBy(actor.actorId)\n    result(actor.name, movie.title)\n}\n\nactedInMovies.size `should be equal to` 3\n\nval (actorName, movieName) = actedInMovieNodes.last()\n\nactorName `should be equal to` \"Carrie Fisher\"\nmovieName `should be equal to` \"Star Wars: Episode V - The Empire Strikes Back\"\n```\n##### Generated Cypher\n```cypher\nMATCH (actor:ActorNode)-[movieRelation:ACTED_IN]-(movie:MovieNode)\nWHERE movie.movie_id = 1\nRETURN actor.name, movie.title\nORDER BY actor.actor_id\n```\n### Delete Nodes And Relationships\nAny nodes or relationships referenced in the Query block can be deleted calling them in the (vararg) delete function:\n```kotlin\nval removedActor = moviesGraph.query {\n    val (actor, relationship) = match(::ActorNode - { actedIn }  - ::MovieNode)\n    where (actor.actorId eq 1)\n    delete(relationship)\n}\n```\n##### Generated Cypher\n```cypher\nMATCH (actor:ActorNode)-[movieRelation:ACTED_IN]-(movie:MovieNode)\nWHERE actor.actor_id = 1\nRETURN movieRelation.role\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnbjhu%2Fkotlinredisgraph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnbjhu%2Fkotlinredisgraph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnbjhu%2Fkotlinredisgraph/lists"}