Closed kristianmandrup closed 7 years ago
db.v()
is a way to define a Variable within a LevelGraph search: https://github.com/mcollina/levelgraph#searches
The webid
or x
in the examples above will become a key name in the search results.
What other documentation would you like to see?
@kristianmandrup you might also dig around in here: https://github.com/warpr/turtle-to-jsonld/blob/master/lib/turtle-to-jsonld.js#L213-L235
Lots of handy utility things in that project that would be nice to see up-streamed and/or extracted eventually.
Cheers! 🎩
Thanks! I will take a look :)
How does jsonld
deal with circular refs? I would assume it just "links" to nodes that only have the @id
?
{
"@id": "mark",
"name": "mark",
"gender": "male",
"self": {
"@id": "mark"
}
}
The triples for that look like this:
<mark> <gender> "male" .
<mark> <name> "mark" .
<mark> <self> <mark> .
Triples are just sentences (conceptually): Subject, Predicate, Object. So, you're basically saying "mark is mark--which is valid, but a bit unnecessary. 😃
Here's some valid JSON-LD (adds a @context
) in the JSON-LD Playground for you to checkout.
Make sense?
Thanks, I'm slowly progressing...
save {
"@context": "http://schema.org/",
"@id": "#mark",
"name": "mark",
"gender": "male",
"wife": {
"@id": "#amber",
"name": "amber",
"gender": "female"
},
"self": {
"@id": "#mark",
"@type": "@id"
}
}
mark was PUT { '@context': 'http://schema.org/',
'@id': '#mark',
name: 'mark',
gender: 'male',
wife: { '@id': '#amber', name: 'amber', gender: 'female' },
self: { '@id': '#mark', '@type': '@id' } }
makeQuery #mark { '@context': 'http://schema.org/' }
GOT mark #mark null
save err Error: Not match for query: #mark in http://schema.org/
So how come I can PUT the above JSON into LevelGraph but there is no match when I try to query? What am I missing in my JsonLd to be valid for querying?
Hmm, when I console.log the get
function I get this signature:
function (iri, context, options, callback)
but in the docs I see this:
db.jsonld.get(manu['@id'], { '@context': manu['@context'] }, function(err, obj) {
// obj will be the very same of the manu object
});
which has 3 arguments if I can count correctly?
Apparently, that JSON-LD isn't being stored when using db.jsonld.put()
--despite it looking like it is being stored...
Try it out on the LevelGraph Playground. You can use db
and jsonld
in the console (as well as db.jsonld
and db.n3
).
What's weird is that if I turn this into N-Quads using the JSON-LD Playground, it does store just fine. However, the JSON-LD version (which is valid JSON-LD) does not store...
@jmatsushita any quick thoughts on this weirdness?
@kristianmandrup also, the options
parameter is optional. :wink:
Thanks, I just looked into the code: index.js#L406 and I discovered what you just said about the optional options
.
Will continue my exploration...
Now I get:
IO error: lock ./gundb/LOCK: already held by process
Can I just delete the ./gundb
folder and start over? or do I need to shut down some process id?
Could be the cause of my problems
Hi there,
When debugging it's usful to see what LevelGraph directly returns (after putting with db.json.ld.put()
) using : db.get({}, console.log);
In this case I think the problem is a missing "@base" in the context, or { base: "http://example.org }
as an option on levelgraph-jsonld creation or passed with .put()
In other words, this works in the Playground:
{
"@context": {
"@vocab": "http://xmlns.com/foaf/0.1/",
"@base": "http://example.org"
},
"@id": "mark",
"name": "mark"
}
What happens behind the scenes (apart from not generating a useful error, which seems worth an issue) is that @id is not understood as a IRI. But that's not valid RDF. i.e. You can't say something about literals ("mark" is a string literal). Whereas "http://example.org/mark" is a resource and you can say things about it!
Cheers,
Jun
The locking error is because levelup is not multi user by default. So indeed you must have another process with the db opened. As long as you don't have important data in it then deleting is an option. Killing zombie processes which might have the file locked is another (maybe best to take the habit of doing that instead of a delete...).
The minimal case I got working is this:
let mark = {
"@context": "http://schema.org/",
"@id": "http:#mark",
"name": "mark"
}
The @id
fields needs to be prefixed with http:
or some protocol. Even h:#mark
works, but not #mark
on its own.
Even :mark
worked, but it was much slower in my case. mark
or #mark
fails.
In you case, open the db with a base
option as described in the usage instructions. Note for instance that the JSON-LD Playground has a default 'base' setup automatically: http://json-ld.org/playground/#startTab=tab-expanded&json-ld=%7B%22%40context%22%3A%22http%3A%2F%2Fschema.org%2F%22%2C%22%40id%22%3A%22%23mark%22%2C%22name%22%3A%22mark%22%7D
I've opened an issue about better feedback and validation in this package.
@kristianmandrup :mark
, http:mark
, etc are all valid URI's (though they obviously wouldn't resolve to anything). #mark
doesn't work because it's only a "fragment identifier" and not a complete URI. For instance, ?mark
wouldn't work either because it's only a component of a full URI (the query string) and not an "absolute" URI.
The guiding principle here is known as the "open-world assumption" (OWA). Essentially, even "local" data identifiers need to be created in such a way that if they were to "surface" on the wider Web, they would not (ideally) conflict with anyone elses data. This is the reason that LevelGraph uses UUID-based blank nodes (_:
prefixed UUIDs) rather than localized _:b1
(etc) style blank nodes.
LevelGraph does provide a way to set your own base
URI (similar to how the JSON-LD Playground uses it's URI as the base). You can also do this per-PUT as @jmatsushita mentioned.
Ideally, though, your JSON-LD will already be using full URI's for @id
values or will reference a @base
URI within the JSON-LD (or within the @context
you construct for your database or documents).
It can take a bit to shake the RDMS/"close world assumption" thinking, but the exchange is well worth it.
Thanks, I just tried different ids...
let mark = {
"@context": "http://schema.org/",
"@id": ":mark",
"name": "mark",
}
let mark1 = {
"@context": "http://www.schema.org",
"@id": "person:mark",
"name": "mark",
"gender": "male",
"wife": {
"@id": "person:amber",
"name": "amber",
"gender": "female"
}
}
let mark2 = {
"@context": "http://www.schema.org",
"@id": "http://www.schema.org/mark",
"name": "mark",
"gender": "male",
"wife": {
"@id": "http://www.schema.org/amber",
"name": "amber",
"gender": "female"
}
}
Huge performance differences on GET. First one less than 1 sec. Next one around 2 secs. Last one seems to time out :O
I will look at the base
option in the usage instructions. At least I kinda got it all working now :)
I'm using this as my default DB options
const jsonldOpts = {
base: 'http://gun.io/base'
}
console.log('jsonld db', jsonldOpts)
jsonld(lvGraphDb, jsonldOpts)
But still person#mark
crashes while person:mark
works. Anyways...
@kristianmandrup what do you mean by "crashes"?
The actual ID you'd be constructing with the @base
+ person#mark
would be "http://gun.io/baseperson#mark`--it is indeed just string concatenation. Likely, that's not what you want.
Also, I'd not mint URI's under other people's domains (i.e. http://schema.org/mark
). I know it's just play-testing at this point, but do try to use valid JSON-LD with some eye toward longevity--your testing will be more accurate and it will also help narrow the source of any bugs.
Lastly, the playgrounds are your friends! :smiley_cat: You can't go wrong by overusing them to test your JSON-LD before tossing it at the database:
Cheers!
All good :) I finally got the hang of it. First time I play for real with a semantic web DB since ages ago with RDF. Cheers! 😺
If you're happy with the result, would you mind closing this issue @kristianmandrup?
Thanks and have fun with LevelGraph!
Where can I find the API for
db.v('webid')
?I see another example on the levelgraph Readme, so now I guess it is just a way to indicate which subjects should match which objects and such in the query. Makes sense, reminds me of Datomic from ClojureScript, using
q?
convention to the same effect... Would be nice if that was documented in the examples. Thanks :)