You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.8 KiB

Logo

GitHub Workflow Status Crates.io GitHub

cozo

A general-purpose, transactional, relational database that uses Datalog for query, embeddable but can also handle huge amount of data and concurrency, and focuses on graph data and algorithms.

What do you mean by embeddable?

What is so cool about Datalog?

Why graphs?

Learning

Usually, to learn a database, you need to install it first. This is unnecessary for Cozo as a testimony to its extreme embeddability, since you can run a complete Cozo instance in your browser (at near native speed for most operations)!

So open up the Cozo in WASM page, and then:

  • Follow the tutorial to learn the basics;
  • Read the manual for the finer points.

After you have decided that Cozo is worth experimenting for your next project, you can scroll down to learn how to use it embedded (or not) in your favourite environment.

Teasers

If you just want a taste of what querying with Cozo is like, here it is. In the following *route is a relation with two columns fr and to, representing a route between those airports, and FRA is the code for Frankfurt Airport.

How many airports are directly connected to FRA?

?[count_unique(to)] := *route{fr: 'FRA', to}
count_unique(to)
310

How many airports are reachable from FRA by one stop?

?[count_unique(to)] := *route{fr: 'FRA', to: 'stop},
                       *route{fr: stop, to}
count_unique(to)
2222

How many airports are reachable from FRA by any number of stops?

count_unique(to)
3462

What are the two most difficult to reach airports by the minimum number of hops required, starting from FRA?

reachable[to] := *route{fr: 'FRA', to}
reachable[to] := reachable[stop], *route{fr: stop, to}
?[count_unique(to)] := reachable[to]
shortest_paths[to, shortest(path)] := *route{fr: 'FRA', to},
                                      path = ['FRA', to]
shortest_paths[to, shortest(path)] := shortest_paths[stop, prev_path],
                                      *route{fr: stop, to},
                                      path = append(prev_path, to)
?[to, path, p_len] := shortest_paths[to, path], p_len = length(path)

:order -p_len
:limit 2
to path p_len
YPO ["FRA","YYZ","YTS","YMO","YFA","ZKE","YAT","YPO"] 8
BVI ["FRA","AUH","BNE","ISA","BQL","BEU","BVI"] 7

What is the shortest path between FRA and YPO, by actual distance travelled?

start[] <- [['FRA']]
end[] <- [['YPO]]
?[src, dst, distance, path] <~ ShortestPathDijkstra(*route[], start[], end[])
src dst distance path
FRA YPO 4544.0 ["FRA","YUL","YVO","YKQ","YMO","YFA","ZKE","YAT","YPO"]

Cozo attempts to provide nice error messages when you make mistakes:

?[x, Y] := x = 1, y = x + 1
eval::unbound_symb_in_head

  × Symbol 'Y' in rule head is unbound
   ╭────
 1 │ ?[x, Y] := x = 1, y = x + 1
   · 
   ╰────
  help: Note that symbols occurring only in negated positions are not considered bound

Install

How you install Cozo depends on where you want to use it from. Follow the links in the table below:

Language/Environment Official platform support Storage
Python Linux (x86_64), Mac (ARM64, x86_64), Windows (x86_64) MQR
NodeJS Linux (x86_64, ARM64), Mac (ARM64, x86_64), Windows (x86_64) MQR
Web browser Modern browsers supporting web assembly M
Java (JVM) Linux (x86_64), Mac (ARM64, x86_64), Windows (x86_64) MQR
Clojure (JVM) Linux (x86_64), Mac (ARM64, x86_64), Windows (x86_64) MQR
Android Android (ARM64, ARMv7, x86_64, x86) MQ
iOS/MacOS (Swift) iOS (ARM64, simulators), Mac (ARM64, x86_64) MQ
Rust Source only, usable on any platform with std support MQRST
Golang Linux (x86_64, ARM64), Mac (ARM64, x86_64), Windows (x86_64) MQR
C/C++/language with C FFI Linux (x86_64, ARM64), Mac (ARM64, x86_64), Windows (x86_64) MQR
Standalone HTTP server Linux (x86_64, ARM64), Mac (ARM64, x86_64), Windows (x86_64) MQRST

For the storage column:

  • M: in-memory, non-persistent backend
  • Q: SQLite storage backend
  • R: RocksDB storage backend
  • S: Sled storage backend
  • T: TiKV distributed storage backend

The Rust doc has some tips on choosing storage, which is helpful even if you are not using Rust. Even if a storage/platform is not officially supported, you can still try to compile your own version to use, maybe with some tweaks in code.

Architecture

Status of the project

Cozo is very young and not production-ready yet, but we encourage you to try it out for your use case. Any feedback is welcome.

Versions before 1.0 do not promise syntax/API stability or storage compatibility.

Licensing

This project are licensed under MPL-2.0 or later. See here if you are interested in contributing to the project.