{"id":40984671,"url":"https://github.com/datalevin/datalevin","last_synced_at":"2026-05-28T04:01:07.228Z","repository":{"id":37501964,"uuid":"270858421","full_name":"datalevin/datalevin","owner":"datalevin","description":"A simple, fast and versatile Datalog database","archived":false,"fork":false,"pushed_at":"2026-05-22T23:54:18.000Z","size":71125,"stargazers_count":1424,"open_issues_count":35,"forks_count":79,"subscribers_count":24,"default_branch":"master","last_synced_at":"2026-05-23T01:24:57.244Z","etag":null,"topics":["ai-native","client-server-database","document-database","embedded-database","fulltext-search","graph-database","key-value-store","vector-database"],"latest_commit_sha":null,"homepage":"https://github.com/datalevin/datalevin","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datalevin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"huahaiy"}},"created_at":"2020-06-08T23:53:52.000Z","updated_at":"2026-05-20T04:50:37.000Z","dependencies_parsed_at":"2023-10-01T23:30:07.893Z","dependency_job_id":"adadd894-72d8-4dd6-8358-f942d3fe54ed","html_url":"https://github.com/datalevin/datalevin","commit_stats":{"total_commits":1933,"total_committers":76,"mean_commits":25.43421052631579,"dds":0.281427832384894,"last_synced_commit":"13f83abcd29ecb850a3694e774c7fd34191adc14"},"previous_names":[],"tags_count":232,"template":false,"template_full_name":null,"purl":"pkg:github/datalevin/datalevin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdatalevin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdatalevin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdatalevin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdatalevin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datalevin","download_url":"https://codeload.github.com/datalevin/datalevin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdatalevin/sbom","scorecard":{"id":541108,"data":{"date":"2025-08-11","repo":{"name":"github.com/juji-io/datalevin","commit":"4289de2c3577ca59190f2349a77dd23cd0814139"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.binaries.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Eclipse Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.9.22 not signed: https://api.github.com/repos/juji-io/datalevin/releases/206714278","Warn: release artifact 0.9.21 not signed: https://api.github.com/repos/juji-io/datalevin/releases/206520223","Warn: release artifact 0.9.20 not signed: https://api.github.com/repos/juji-io/datalevin/releases/201289818","Warn: release artifact 0.9.19 not signed: https://api.github.com/repos/juji-io/datalevin/releases/201258895","Warn: release artifact 0.9.18 not signed: https://api.github.com/repos/juji-io/datalevin/releases/195776605","Warn: release artifact 0.9.22 does not have provenance: https://api.github.com/repos/juji-io/datalevin/releases/206714278","Warn: release artifact 0.9.21 does not have provenance: https://api.github.com/repos/juji-io/datalevin/releases/206520223","Warn: release artifact 0.9.20 does not have provenance: https://api.github.com/repos/juji-io/datalevin/releases/201289818","Warn: release artifact 0.9.19 does not have provenance: https://api.github.com/repos/juji-io/datalevin/releases/201258895","Warn: release artifact 0.9.18 does not have provenance: https://api.github.com/repos/juji-io/datalevin/releases/195776605"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:65: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.binaries.yml:83: update your workflow using https://app.stepsecurity.io/secureworkflow/juji-io/datalevin/release.binaries.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T08:14:04.171Z","repository_id":37501964,"created_at":"2025-08-20T08:14:04.172Z","updated_at":"2025-08-20T08:14:04.172Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33593400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ai-native","client-server-database","document-database","embedded-database","fulltext-search","graph-database","key-value-store","vector-database"],"created_at":"2026-01-22T07:22:54.363Z","updated_at":"2026-05-28T04:01:07.220Z","avatar_url":"https://github.com/datalevin.png","language":"Clojure","funding_links":["https://github.com/sponsors/huahaiy"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"logo.png\" alt=\"datalevin logo\"\nheight=\"140\"\u003e\u003c/img\u003e\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eDatalevin\u003c/h1\u003e\n\u003cp align=\"center\"\u003e 🧘 Simple, fast and versatile Datalog database for everyone\n💽 \u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://cljdoc.org/d/datalevin/datalevin\"\u003e\u003cimg\nsrc=\"https://cljdoc.org/badge/datalevin/datalevin\" alt=\"datalevin on\ncljdoc\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003ca href=\"https://clojars.org/datalevin\"\u003e\u003cimg\nsrc=\"https://img.shields.io/clojars/v/datalevin.svg?color=success\"\nalt=\"datalevin on clojars\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003ca href=\"https://central.sonatype.com/artifact/org.datalevin/datalevin-java\"\u003e\u003cimg\nsrc=\"https://img.shields.io/maven-central/v/org.datalevin/datalevin-java.svg?color=success\"\nalt=\"datalevin-java on maven central\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/datalevin-node\"\u003e\u003cimg\nsrc=\"https://img.shields.io/npm/v/datalevin-node.svg?color=success\"\nalt=\"datalevin-node on npm\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/datalevin/\"\u003e\u003cimg\nsrc=\"https://img.shields.io/pypi/v/datalevin.svg?color=success\"\nalt=\"datalevin on pypi\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003ca\nhref=\"https://github.com/datalevin/datalevin/blob/master/doc/install.md#babashka-pod\"\u003e\u003cimg\nsrc=\"https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg\"\nalt=\"bb compatible\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/datalevin/datalevin/actions\"\u003e\u003cimg\nsrc=\"https://github.com/datalevin/datalevin/actions/workflows/release.binaries.yml/badge.svg\"\nalt=\"datalevin linux/macos amd64 build status\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003e I love Datalog, why hasn't everyone used this already?\n\n**Datalevin** (/ˈdadə ˈlevən/, \"levin\" means \"lightning\") is a simple durable\n[Datalog](https://en.wikipedia.org/wiki/Datalog) database. Here's what a Datalog\nquery looks like in Datalevin:\n\n```Clojure\n(d/q '[:find  ?name ?total\n       :in    $ ?year\n       :where [?sales :sales/year ?year]\n              [?sales :sales/total ?total]\n              [?sales :sales/customer ?customer]\n              [?customer :customers/name ?name]]\n      (d/db conn) 2024)\n```\n\n## :question: Why\n\nThe rationale is to have a simple, fast, versatile and open source Datalog query\nengine running on durable storage.\n\nIt is our observation that many developers prefer\nthe flavor of Datalog popularized by [Datomic®](https://www.datomic.com) over\nany flavor of SQL, once they get to use it. Perhaps it is because Datalog is\nmore declarative and composable than SQL, e.g. the automatic implicit joins seem\nto be its killer feature. In addition, the recursive rules feature of Datalog\nmakes it suitable for [graph queries](benchmarks/LDBC-SNB-bench) and\n[deductive reasoning](benchmarks/math-bench).\n\nThe feature set of Datomic® may not be a good fit for some use cases. One thing\nthat may [confuse some\nusers](https://vvvvalvalval.github.io/posts/2017-07-08-Datomic-this-is-not-the-history-youre-looking-for.html)\nis its [temporal\nfeatures](https://docs.datomic.com/cloud/whatis/data-model.html#time-model). To\nkeep things simple and familiar, Datalevin behaves the same way as most other\ndatabases: when data are deleted, they are gone. Datalevin also follows the\nwidely accepted principles of ACID, instead of introducing [unusual\nsemantics](https://jepsen.io/analyses/datomic-pro-1.0.7075).\n\nIn addition to support Datomic® flavor of Datalog query language, Datalevin has\na [novel cost-based query optimizer](doc/query.md) with a much better query\nperformance, which is competitive with SQL RDBMS such as\n[PostgreSQL](benchmarks/JOB-bench) and graph databases such as\n[Neo4j](benchmarks/LDBC-SNB-bench).\n\nDatalevin provides robust ACID transaction features on the basis of [our\nfork](https://github.com/huahaiy/dlmdb) of\n[LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database), known\nfor its high read performance. With built-in support for WAL and\nasynchronous transaction, Datalevin can also handle [write intensive\nworkload](benchmarks/write-bench).\n\nDatalevin can store large document (\u003c 2 GiB) and automatically build index by\npaths for JSON, EDN and Markdown [documents](doc/idoc.md), so it can be used as\na document database, similar to MongoDB or PostgreSQL JSONB column.\n\nDatalevin supports [vector database](doc/vector.md) features by integrating an\nefficient SIMD accelerated vector indexing and search\n[library](https://github.com/unum-cloud/usearch). Datalevin has a [novel full-text search\nengine](doc/search.md) that has [competitive](benchmarks/search-bench) search\nperformance.\n\nDatalevin is also AI-native. It ships with a built-in local [MCP\nserver](doc/mcp.md). Datalevin supports in-DB embedding and text generation with\nbuilt-in [llama.cpp](https://github.com/ggml-org/llama.cpp), and compatible\nOCR-capable generation models can be used for OCR workflows, so\nAI clients can query Datalevin over MCP while RAG applications keep embedding\ngeneration and search in the same database runtime.\n\nDatalevin can be used as a fast key-value store for\n[EDN](https://en.wikipedia.org/wiki/Extensible_Data_Notation) data. The native\nEDN data capability of Datalevin should be beneficial for Clojure programs.\n\nDatalevin can be used as a library, embedded in applications to manage state,\ne.g. used like SQLite; or it can run in a networked\n[client/server](https://github.com/datalevin/datalevin/blob/master/doc/server.md)\nmode (default port is 8898) with a Raft consensus based high availability\ncluster configuration with full-fledged role-based access control (RBAC); or it\ncan be used as a [babashka\npod](https://github.com/babashka/pod-registry/blob/master/examples/datalevin.clj)\nfor shell scripting.\n\nFor embedded usage, [Java](examples/java/README.md),\n[Python](bindings/python/README.md), [Node.js](bindings/javascript/README.md)\nand [Clojure](https://cljdoc.org/d/datalevin/datalevin) are currently supported.\n\nMore information about our vision and design decisions can be found in these\narticles and presentation:\n\n* [Triple Store, Triple Progress: Datalevin Posited for the Future](https://yyhh.org/blog/2026/01/triple-store-triple-progress-datalevin-posited-for-the-future/)\n* [Achieving High Throughput and Low Latency through Adaptive Asynchronous Transaction](https://yyhh.org/blog/2025/02/achieving-high-throughput-and-low-latency-through-adaptive-asynchronous-transaction/)\n* [Competing for the JOB with a Triplestore](https://yyhh.org/blog/2024/09/competing-for-the-job-with-a-triplestore/)\n* [If I had to Pick One: Datalevin](https://vimsical.notion.site/If-I-Had-To-Pick-One-Datalevin-be5c4b62cda342278a10a5e5cdc2206d)\n* [T-Wand: Beat Lucene in Less Than 600 Lines of Code](https://yyhh.org/blog/2021/11/t-wand-beat-lucene-in-less-than-600-lines-of-code/)\n* [2020 London Clojurians Meetup](https://youtu.be/-5SrIUK6k5g)\n\n## :truck: [Installation](doc/install.md)\n\nAs a Clojure library, Datalevin is simple to add as a dependency to your Clojure\nproject. There are also several other installation options. Please see details in\n[Installation Documentation](doc/install.md)\n\nFor embedded-only JVM consumers, Clojars also publishes\n`org.datalevin/datalevin-embedded:0.10.17`, which keeps the local APIs and\n`datalevin.client` while trimming the server, HA, CLI, and babashka pod runtime.\n\n## :birthday: Upgrade\n\nPlease read\n[Upgrade\nDocumentation](https://github.com/datalevin/datalevin/blob/master/doc/upgrade.md)\nfor information regarding upgrading your existing Datalevin database from older\nversions.\n\n## :tada: Usage\n\nDatalevin is aimed to be a versatile database.\n\n### Use as a Datalog store\n\nIn addition to [our API doc](https://cljdoc.org/d/datalevin/datalevin),\nDatalevin has almost the same Datalog API as\n[Datascript](https://github.com/tonsky/datascript), which in turn has almost the\nsame API as Datomic®, please consult the abundant tutorials, guides and learning\nsites available online to learn about the usage of Datomic® flavor of Datalog.\nFor descriptor-backed transaction/query UDFs and server-side runtime setup, see\n[Transactions](doc/transact.md), [Query](doc/query.md), and\n[Server](doc/server.md).\n\nHere is a simple code example using Datalevin:\n\n```clojure\n(require '[datalevin.core :as d])\n\n;; Define an optional schema.\n;; Note that pre-defined schema is optional, as Datalevin does schema-on-write.\n;; However, attributes requiring special handling need to be defined in schema,\n;; e.g. range query, many cardinality, uniqueness, reference type, etc.\n;; Similar to Datascript, Datalevin schemas differ from Datomic®:\n;; - The schema must be a map of maps, not a vector of maps.\n;; - It is not `transact`ed into the db but passed when acquiring connections.\n;; - Use `update-schema` to update the schema of an open connection to a DB.\n(def schema {:aka  {:db/cardinality :db.cardinality/many}\n             ;; :db/valueType is optional, if unspecified, the attribute will be\n             ;; treated as EDN blobs, and may not be optimal for range queries\n             :name {:db/valueType :db.type/string\n                    :db/unique    :db.unique/identity}})\n\n;; Create DB on disk and connect to it, assume write permission to create the dir\n(def conn (d/get-conn \"/tmp/datalevin/mydb\" schema))\n;; or if you have a Datalevin server running on myhost with default port 8898\n;; (def conn (d/get-conn \"dtlv://myname:mypasswd@myhost/mydb\" schema))\n\n;; Transact some data\n;; `:nation` is not defined in schema, so it will be treated as an EDN blob\n(d/transact! conn\n            [{:name \"Frege\", :db/id -1, :nation \"France\", :aka [\"foo\" \"fred\"]}\n             {:name \"Peirce\", :db/id -2, :nation \"france\"}\n             {:name \"De Morgan\", :db/id -3, :nation \"English\"}])\n\n;; Query the data\n(d/q '[:find ?nation\n       :in $ ?alias\n       :where\n       [?e :aka ?alias]\n       [?e :nation ?nation]]\n     (d/db conn)\n     \"fred\")\n;; =\u003e #{[\"France\"]}\n\n;; Retract the name attribute of an entity\n(d/transact! conn [[:db/retract 1 :name \"Frege\"]])\n\n;; Pull the entity, now the name is gone\n(d/q '[:find (pull ?e [*])\n       :in $ ?alias\n       :where\n       [?e :aka ?alias]]\n     (d/db conn)\n     \"fred\")\n;; =\u003e ([{:db/id 1, :aka [\"foo\" \"fred\"], :nation \"France\"}])\n\n;; Close DB connection\n(d/close conn)\n```\n\n### Use as a key-value store\n\nDatalevin packages the underlying LMDB database as a convenient key-value store\nfor EDN data.\n\n```clojure\n(require '[datalevin.core :as d])\n(import '[java.util Date])\n\n;; Open a key value DB on disk and get the DB handle\n(def db (d/open-kv \"/tmp/datalevin/mykvdb\"))\n;; or if you have a Datalevin server running on myhost with default port 8898\n;; (def db (d/open-kv \"dtlv://myname:mypasswd@myhost/mykvdb\" schema))\n\n;; Define some table (called \"dbi\", or sub-databases in LMDB) names\n(def misc-table \"misc-test-table\")\n(def date-table \"date-test-table\")\n\n;; Open the tables\n(d/open-dbi db misc-table)\n(d/open-dbi db date-table)\n\n;; Transact some data, a transaction can put data into multiple tables\n;; Optionally, data type can be specified to help with range query\n(d/transact-kv\n  db\n  [[:put misc-table :datalevin \"Hello, world!\"]\n   [:put misc-table 42 {:saying \"So Long, and thanks for all the fish\"\n                        :source \"The Hitchhiker's Guide to the Galaxy\"}]\n   [:put date-table #inst \"1991-12-25\" \"USSR broke apart\" :instant]\n   [:put date-table #inst \"1989-11-09\" \"The fall of the Berlin Wall\" :instant]])\n\n;; Get the value with the key\n(d/get-value db misc-table :datalevin)\n;; =\u003e \"Hello, world!\"\n(d/get-value db misc-table 42)\n;; =\u003e {:saying \"So Long, and thanks for all the fish\",\n;;     :source \"The Hitchhiker's Guide to the Galaxy\"}\n\n\n;; Range query, from unix epoch time to now\n(d/get-range db date-table [:closed (Date. 0) (Date.)] :instant)\n;; =\u003e [[#inst \"1989-11-09T00:00:00.000-00:00\" \"The fall of the Berlin Wall\"]\n;;     [#inst \"1991-12-25T00:00:00.000-00:00\" \"USSR broke apart\"]]\n\n;; This returns a PersistentVector - e.g. reads all data in JVM memory\n(d/get-range db misc-table [:all])\n;; =\u003e [[42 {:saying \"So Long, and thanks for all the fish\",\n;;          :source \"The Hitchhiker's Guide to the Galaxy\"}]\n;;     [:datalevin \"Hello, world!\"]]\n\n;; This allows you to iterate over all DB keys inside a transaction.\n;; You can perform writes inside the transaction.\n;; Avoid long-lived transactions. Read transactions prevent reuse of pages freed\n;; by newer write transactions, thus the database can grow quickly.\n;; Write transactions prevent other write transactions, since writes are serialized.\n(d/visit db misc-table\n            (fn [kv]\n               (let [k (d/read-buffer (d/k kv) :data)]\n                  (when (= k 42)\n                    (d/transact-kv db [[:put misc-table 42 \"Don't panic\"]]))))\n              [:all])\n\n(d/get-range db misc-table [:all])\n;; =\u003e [[42 \"Don't panic\"] [:datalevin \"Hello, world!\"]]\n\n;; Delete some data\n(d/transact-kv db [[:del misc-table 42]])\n\n;; Now it's gone\n(d/get-value db misc-table 42)\n;; =\u003e nil\n\n;; Close key value db\n(d/close-kv db)\n\n```\n\n## :green_book: Documentation\n\nPlease refer to the [API\ndocumentation](https://cljdoc.org/d/datalevin/datalevin) for more details.\nThe [WAL guide](doc/wal.md) documents durability profiles, risk-window knobs,\nand WAL operational APIs.\n\n## :bar_chart: Benchmarks\n\nThis repository contains several [benchmarks](benchmarks) that compare\nperformance of Datalevin with other databases.\n\nWe compared Datalevin with PostgreSQL and SQLite in handling complex queries, using\n[Join Order Benchmark](benchmarks/JOB-bench). On a\nMacBook Pro, Apple M3 chip with 12 cores, 30 GB memory and 1TB SSD drive, the\nchart below plots query latency for all 113 queries in the benchmark.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"benchmarks/JOB-bench/job_benchmark_log_bars.svg\" alt=\"JOB benchmark\" height=\"300\"\u003e\u003c/img\u003e\n\u003c/p\u003e\n\nDatalevin is about 2.4X faster than PostgreSQL and 4X faster than SQLite\non average in running these complex queries that involves many joins. The gain\nis mainly due to shorter query execution time as Datalevin's query optimizer\ngenerates better plans. Details of the analysis can be found in [this\narticle](https://yyhh.org/blog/2024/09/competing-for-the-job-with-a-triplestore/)\n\nFor durable transaction performance, we compared Datalevin with\nSQLite using [this write benchmark](benchmark/write-bench) on a 2016 Ubuntu\nLinux server with an Intel i7 3.6GHz CPU and a 1TB SSD drive.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"benchmarks/write-bench/throughput-1.png\" alt=\"Throughput at 1\" height=\"300\"\u003e\u003c/img\u003e\n\u003c/p\u003e\n\nWhen transacting one entity (equivalently, one row in SQLite) at a time,\nDatalevin's default transaction function is over 5X faster than SQLite's\ndefault; while Datlevin's asynchronous transaction mode is over 20X faster than\nSQLite's WAL mode.\n\nFor performance comparison with [Datomic](https://www.datomic.com) and\n[Datascript](https://github.com/tonsky/datascript), see the [DataScript\nbenchmark](benchmarks/datascript-bench). Run on an Apple M3 Pro with all three\ndatabases in in-memory mode, Datalevin is competitive on write operations, and\nsignificantly outperforms both on complex read queries due to its query\noptimizer. For example, Datalevin is over 13X faster than Datascript on a\n3-way join query and nearly 18X faster on a 4-way join.\n\nDatalevin also has an advanced [rule engine](doc/rules.md), which is much faster\nthan Datomic and Datascript that implement the same rule language. [This\nbenchmark](benchmarks/math-bench) shows the running time in milliseconds of\napplying 4 rules to a mathematics genealogy data set on a Macbook Pro 2023.\n\n| System    | Q1 | Q2 | Q3 | Q4\n| -------- | ------- | -------- | -------- | -------- |\n| Datomic 1.0.7469   | 1275.1 | 1296.7 | 967.2 | 41192.9 |\n| Datascript 1.7.8  | 109.7 | 707.2 | 584.7 | Out of Memory |\n| Datalevin latest | 14.4 | 330.9 | 269.6 | 2.9 |\n\nFor recursive rules like Q4, Datalevin can be orders of magnitude faster,\nwhile Datomic and Datascript struggle.\n\nDatalevin compares favorably with Neo4j on [an industrial standard graph\ndatabase benchmark](benchmarks/LDBC-SNB-bench). For point access in\ngraphs, Datalevin is several orders of magnitude faster, while performs\ncomparably with Neo4j on complex graph queries.\n\n## :rocket: Status\n\nDatalevin is extensively tested with property-based testing and is used\nin production at [Juji](https://juji.io), among other companies.\n\n## :earth_americas: Roadmap\n\nThe goal of Datalevin is to simplify data storage and access. We aim to support\ndiverse workloads and use cases. Below are the tentative goals that we try to\nreach as soon as we can. We may adjust the priorities based on feedback.\n\n* 0.4.0 ~~Native image and native command line tool.~~ [Done 2021/02/27]\n* 0.5.0 ~~Networked server mode with role based access control.~~ [Done 2021/09/06]\n* 0.6.0 ~~As a search engine: full-text search across database.~~ [Done 2022/03/10]\n* 0.7.0 ~~Explicit transactions, lazy results loading, and results spill to disk\n  when memory is low.~~ [Done 2022/12/15]\n* 0.8.0 ~~Long ids; composite tuples; enhanced search engine ingestion speed.~~\n  [Done 2023/01/19]\n* 0.9.0 ~~New Datalog query engine with improved performance.~~ [Done 2024/03/09]\n* 0.10.0 ~~Async transaction; boolean search expression and phrase search; as a\n  vector database; counted and prefix compressed KV storage; auto upgrade\n  migration; new rule engine.~~[Done 2026/01/22]\n* 1.0.0 ~~As a document database with automatic path indexing; WAL mode;\n  transaction log access API;~~  read-only replicas; high availability; JSON API;\n  library for Java, Python, and JavaScript;\n* 1.1.0 TTL; extensible storage/query for arbitrary data; data compression.\n* 2.0.0 Incremental view maintenance.\n* 3.0.0 Extended rule syntax to handle complex analytical workload capable of\n  implementing ML algorithms in DB.\n\n## :arrows_clockwise: Contact\n\nDatalevin will remain open source for the foreseeable future. We appreciate and\nwelcome your contributions or suggestions. Please feel free to file issues or\npull requests.\n\nIf commercial support is needed, talk to us.\n\nYou can talk to us in the `#datalevin` channel on [Clojurians Slack](http://clojurians.net/).\n\n## License\n\nCopyright © 2020-2026 [Huahai Yang](https://huahaiy.github.io/) and contributors.\n\nLicensed under Eclipse Public License (see [LICENSE](LICENSE)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatalevin%2Fdatalevin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatalevin%2Fdatalevin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatalevin%2Fdatalevin/lists"}