{"id":19046393,"url":"https://github.com/wallix/triplestore","last_synced_at":"2025-04-16T14:39:47.909Z","repository":{"id":57492236,"uuid":"86672087","full_name":"wallix/triplestore","owner":"wallix","description":"Nifty library to manage, query and store RDF triples. Make RDF great again!","archived":false,"fork":false,"pushed_at":"2019-02-19T16:34:12.000Z","size":1607,"stargazers_count":115,"open_issues_count":4,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-29T05:23:30.779Z","etag":null,"topics":["awless","golang","graph","rdf","triples","triplestore"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wallix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-30T07:24:35.000Z","updated_at":"2024-10-19T12:47:53.000Z","dependencies_parsed_at":"2022-09-02T00:13:28.906Z","dependency_job_id":null,"html_url":"https://github.com/wallix/triplestore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wallix%2Ftriplestore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wallix%2Ftriplestore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wallix%2Ftriplestore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wallix%2Ftriplestore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wallix","download_url":"https://codeload.github.com/wallix/triplestore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249250966,"owners_count":21237965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["awless","golang","graph","rdf","triples","triplestore"],"created_at":"2024-11-08T22:54:38.601Z","updated_at":"2025-04-16T14:39:47.889Z","avatar_url":"https://github.com/wallix.png","language":"Go","funding_links":[],"categories":["Databases"],"sub_categories":["Data Cube extensions"],"readme":"[![Build Status](https://api.travis-ci.org/wallix/triplestore.svg?branch=master)](https://travis-ci.org/wallix/triplestore)\n[![Go Report Card](https://goreportcard.com/badge/github.com/wallix/triplestore)](https://goreportcard.com/report/github.com/wallix/triplestore)\n[![GoDoc](https://godoc.org/github.com/wallix/triplestore?status.svg)](https://godoc.org/github.com/wallix/triplestore) \n\n# Triple Store\n\nTriple Store is a library to manipulate RDF triples in a fast and fluent fashion.\n\nRDF triples allow to represent any data and its relations to other data. It is a very versatile concept and is used in [Linked Data](https://en.wikipedia.org/wiki/Linked_data), graphs traversal and storage, etc....\n\nHere the RDF triples implementation follows along the [W3C RDF concepts](https://www.w3.org/TR/rdf11-concepts/). (**Note that reification is not implemented**.). More digestible info on [RDF Wikipedia](https://en.wikipedia.org/wiki/Resource_Description_Framework)\n\n## Features overview\n\n- Create and manage triples through a convenient DSL\n- Snapshot and query RDFGraphs\n- **Binary** encoding/decoding\n- **Lenient NTriples** encoding/decoding (see W3C Test suite in _testdata/ntriples/w3c_suite/_)\n- [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) encoding\n- Stream encoding/decoding (for binary \u0026 NTriples format) for memory conscious program \n- CLI (Command line interface) utility to read and convert triples files.\n\n## Library \n\nThis library is written using the [Golang](https://golang.org) language. You need to [install Golang](https://golang.org/doc/install) before using it.\n\nGet it:\n\n```sh\ngo get -u github.com/wallix/triplestore\n```\n\nTest it:\n\n```\ngo test -v -cover -race github.com/wallix/triplestore\n```\n\nBench it:\n\n```\ngo test -run=none -bench=. -benchmem\n```\n\nImport it in your source code:\n\n```go\nimport (\n\t\"github.com/wallix/triplestore\"\n\t// tstore \"github.com/wallix/triplestore\" for less verbosity\n)\n```\n\nGet the CLI with:\n\n```\ngo get -u github.com/wallix/triplestore/cmd/triplestore\n```\n\n## Concepts\n\nA triple is made of 3 components:\n\n    subject -\u003e predicate -\u003e object\n\n... or you can also view that as:\n\n    entity -\u003e attribute -\u003e value\n\nSo\n\n- A **triple** consists of a *subject*, a *predicate* and a *object*.\n- A **subject** is a unicode string.\n- A **predicate** is a unicode string.\n- An **object** is a *resource* (or IRI) or a *literal* (blank node are not supported).\n- A **literal** is a unicode string associated with a datatype (ex: string, integer, ...).\n- A **resource**, a.k.a IRI, is a unicode string which point to another resource.\n\nAnd\n\n- A **source** is a persistent yet mutable source or container of triples.\n- A **RDFGraph** is an **immutable set of triples**. It is a snapshot of a source and queryable .\n- A **dataset** is a basically a collection of *RDFGraph*.\n\nYou can also view the library through the [godoc](https://godoc.org/github.com/wallix/triplestore)\n\n## Usage\n\n#### Create triples\n\nAlthough you can build triples the way you want to model any data, they are usually built from known RDF vocabularies \u0026 namespace. Ex: [foaf](http://xmlns.com/foaf/spec/), ...\n\n```go\ntriples = append(triples,\n\tSubjPred(\"me\", \"name\").StringLiteral(\"jsmith\"),\n \tSubjPred(\"me\", \"age\").IntegerLiteral(26),\n \tSubjPred(\"me\", \"male\").BooleanLiteral(true),\n \tSubjPred(\"me\", \"born\").DateTimeLiteral(time.Now()),\n \tSubjPred(\"me\", \"mother\").Resource(\"mum#121287\"),\n)\n```\n\nor dynamically and even shorter with\n\n```go\ntriples = append(triples,\n \tSubjPredLit(\"me\", \"age\", \"jsmith\"), // String literal object\n \tSubjPredLit(\"me\", \"age\", 26), // Integer literal object\n \tSubjPredLit(\"me\", \"male\", true), // Boolean literal object\n \tSubjPredLit(\"me\", \"born\", time.now()) // Datetime literal object\n \tSubjPredRes(\"me\", \"mother\", \"mum#121287\"), // Resource object\n)\n```\n\nor with blank nodes and language tag in literal\n\n```go\ntriples = append(triples,\n \tSubjPred(\"me\", \"name\").Bnode(\"jsmith\"),\n \tBnodePred(\"me\", \"name\").StringLiteral(\"jsmith\"),\n \tSubjPred(\"me\", \"name\").StringLiteralWithLang(\"jsmith\", \"en\"),\n)\n```\n\n#### Create triples from a struct\n\nAs a convenience you can create triples from a singular struct, where you control embedding through bnode.\n\nHere is an example.\n\n```go\ntype Address struct {\n\tStreet string `predicate:\"street\"`\n\tCity   string `predicate:\"city\"`\n}\n\ntype Person struct {\n\tName     string    `predicate:\"name\"`\n\tAge      int       `predicate:\"age\"`\n\tSize     int64     `predicate:\"size\"`\n\tMale     bool      `predicate:\"male\"`\n\tBirth    time.Time `predicate:\"birth\"`\n\tSurnames []string  `predicate:\"surnames\"`\n\tAddr     Address   `predicate:\"address\" bnode:\"myaddress\"` // empty bnode value will make bnode value random\n}\n\naddr := \u0026Address{...}\nperson := \u0026Person{Addr: addr, ....}\n\ntris := TriplesFromStruct(\"jsmith\", person)\n\nsrc := NewSource()\nsrc.Add(tris)\nsnap := src.Snapshot()\n\nsnap.Contains(SubjPredLit(\"jsmith\", \"name\", \"...\"))\nsnap.Contains(SubjPredLit(\"jsmith\", \"size\", 186))\nsnap.Contains(SubjPredLit(\"jsmith\", \"surnames\", \"...\"))\nsnap.Contains(SubjPredLit(\"jsmith\", \"surnames\", \"...\"))\nsnap.Contains(SubjPred(\"me\", \"address\").Bnode(\"myaddress\"))\nsnap.Contains(BnodePred(\"myaddress\", \"street\").StringLiteral(\"5th avenue\"))\nsnap.Contains(BnodePred(\"myaddress\", \"city\").StringLiteral(\"New York\"))\n```\n\n#### Equality\n\n```go\n\tme := SubjPred(\"me\", \"name\").StringLiteral(\"jsmith\")\n \tyou := SubjPred(\"me\", \"name\").StringLiteral(\"fdupond\")\n\n \tif me.Equal(you) {\n \t \t...\n \t}\n)\n```\n\n### Triple Source\n\nA source is a persistent yet mutable source or container of triples\n\n```go\nsrc := tstore.NewSource()\n\nsrc.Add(\n\tSubjPredLit(\"me\", \"age\", \"jsmith\"),\n\tSubjPredLit(\"me\", \"born\", time.now()),\n)\nsrc.Remove(SubjPredLit(\"me\", \"age\", \"jsmith\"))\n```\n\n### RDFGraph\n\nA RDFGraph is an immutable set of triples you can query. You get a RDFGraph by snapshotting a source:\n\n```go\ngraph := src.Snapshot()\n\ntris := graph.WithSubject(\"me\")\nfor _, tri := range tris {\n\t...\n}\n```\n\n### Codec\n\nTriples can be encoded \u0026 decoded using either a simple binary format or more standard text format like NTriples, ...\n\nTriples can therefore be persisted to disk, serialized or sent over the network.\n\nFor example\n\n```go\nenc := NewBinaryEncoder(myWriter)\nerr := enc.Encode(triples)\n...\n\ndec := NewBinaryDecoder(myReader)\ntriples, err := dec.Decode()\n```\n\nCreate a file of triples under the lenient NTriples format:\n\n```go\nf, err := os.Create(\"./triples.nt\")\nif err != nil {\n\treturn err\n}\ndefer f.Close()\n\nenc := NewLenientNTEncoder(f)\nerr := enc.Encode(triples)\n\n``` \n\nEncode to a DOT graph\n```go\ntris := []Triple{\n        SubjPredRes(\"me\", \"rel\", \"you\"),\n        SubjPredRes(\"me\", \"rdf:type\", \"person\"),\n        SubjPredRes(\"you\", \"rel\", \"other\"),\n        SubjPredRes(\"you\", \"rdf:type\", \"child\"),\n        SubjPredRes(\"other\", \"any\", \"john\"),\n}\n\nerr := NewDotGraphEncoder(file, \"rel\").Encode(tris...)\n...\n\n// output\n// digraph \"rel\" {\n//  \"me\" -\u003e \"you\";\n//  \"me\" [label=\"me\u003cperson\u003e\"];\n//  \"you\" -\u003e \"other\";\n//  \"you\" [label=\"you\u003cchild\u003e\"];\n//}\n```\n\nLoad a binary dataset (i.e. multiple RDFGraph) concurrently from given files:\n\n```go\npath := filepath.Join(fmt.Sprintf(\"*%s\", fileExt))\nfiles, _ := filepath.Glob(path)\n\nvar readers []io.Reader\nfor _, f := range files {\n\treader, err := os.Open(f)\n\tif err != nil {\n\t\treturn g, fmt.Errorf(\"loading '%s': %s\", f, err)\n\t}\n\treaders = append(readers, reader)\n}\n\ndec := tstore.NewDatasetDecoder(tstore.NewBinaryDecoder, readers...)\ntris, err := dec.Decode()\nif err != nil {\n\treturn err\n}\n...\n```\n\n### triplestore CLI\n\nThis CLI is mainly ised for triples files conversion and inspection. Install it with `go get github.com/wallix/triplestore/cmd/triplestore`. Then `triplestore -h` for help.\n\nExample of usage:\n\n```sh\ntriplestore -in ntriples -out bin -files fuzz/ntriples/corpus/samples.nt \ntriplestore -in ntriples -out bin -files fuzz/ntriples/corpus/samples.nt \ntriplestore -in bin -files fuzz/binary/corpus/samples.bin\n```\n\n### RDFGraph as a Tree\n\nA tree is defined from a RDFGraph given:\n\n * a specific predicate as an edge\n * and considering triples pointing to RDF resource Object \n\nYou can then navigate the tree using the existing API calls\n\n\ttree := tstore.NewTree(myGraph, myPredicate)\n\ttree.TraverseDFS(...)\n\ttree.TraverseAncestors(...)\n\ttree.TraverseSiblings(...)\n\nHave a look at the [godoc](https://godoc.org/github.com/wallix/triplestore) fro more info \n\nNote that at the moment, constructing a new tree from a graph does not verify if the tree is valid namely no cycle and each child at most one parent.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwallix%2Ftriplestore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwallix%2Ftriplestore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwallix%2Ftriplestore/lists"}