falkordb
FalkorDB
This shard is a Crystal client for FalkorDB, a graph database built on top of Redis.
Installation
-
Add the dependency to your
shard.yml
:dependencies: falkordb: github: jgaskins/falkordb
-
Run
shards install
Usage
require "falkordb"
redis = Redis::Client.new
graph = FalkorDB::Graph.new(redis, "your-graph-key")
Then, when you run your queries, use the read_query
and write_query
methods. If you're using a Redis::ReplicationClient
, this will automatically route write queries to the primary and read queries to replicas.
graph.write_query <<-CYPHER
CREATE (user:User {
id: randomUUID(),
name: "Jamie"
})
CYPHER
Specifying query return type
You can set the return type of the results using the return:
argument. This must match the types of the values in your Cypher query's RETURN
clause.
# We need to get the first result from the result set to get the id itself
id = graph.write_query(<<-CYPHER, return: UUID).first
CREATE (user:User {
id: randomUUID(),
name: "Jamie"
})
RETURN user.id
CYPHER
Returning multiple values per result
If your RETURN
clause has multiple values, you can specify their types using tuples:
graph.read_query(<<-CYPHER, return: {User, Team})
MATCH (user:User)-[:MEMBER_OF]->(team:Team)
RETURN user, team
CYPHER
Passing query parameters
If you need to pass values to your query, it's best to use query parameters rather than interpolate them into the strings. This offers the same benefits as for SQL databases:
- Improved performance via caching query plans
- Avoiding query injection via malformed values
To pass query parameters, simply place them after your Cypher query. For example, to get all of the teams the current user is a member of, you might use a query that looks like this:
graph.read_query <<-CYPHER, {user_id: current_user.id}, return: Team do |team|
MATCH (user:User{id: $user_id})-[:MEMBER_OF]->(team:Team)
RETURN team
CYPHER
Defining custom node/relationship types
You can represent nodes and relationships in your graph using your own Crystal types with certain properties automatically deserialized into other types for you. For example, let's say you have a Post
type:
struct Post
include FalkorDB::Serializable::Node
getter id : UUID
getter body : String
getter created_at : Time
end
If your id
is stored as a string (generated with the randomUUID()
function, for example) and your created_at
property is stored as a Unix millisecond timestamp (via Time#to_unix_ms
), this post can be automatically deserialized:
graph.read_query(<<-CYPHER, return: Post).each do |post|
MATCH (post:Post)
RETURN post
CYPHER
# ...
end
Contributing
- Fork it (https://github.com/jgaskins/falkordb/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Jamie Gaskins - creator and maintainer
falkordb
- 2
- 0
- 0
- 0
- 1
- 25 days ago
- July 5, 2025
MIT License
Wed, 30 Jul 2025 02:07:57 GMT