How to enforce an array on "#type" in jsonld? - json-ld

Given a context with an aliased type like this:
{
"#context" : {
"type" : "#type"
}
}
How can an array be enforced onto the data like with using
"#container" : "#set"
?

In JSON-LD 1.0 this can't be achieved, as #type has its definition fixed by the specification. You can create aliases (such as type) but you can't change the behavior.
In the forthcoming JSON-LD 1.1, this has issue has been solved, and you can do exactly as proposed -- add #container: #set to the definition, and the compaction algorithm will add the types to an array.
The relevant issue in the 1.1 working group: https://github.com/w3c/json-ld-syntax/issues/34

Related

JSON-LD can't define multiple node types in #context

The documentation of JSON-LD types clearly states that you can define multiple types to a node.
https://www.w3.org/TR/json-ld11/#specifying-the-type
If you open the example #14 from the above url in the JSON-LD playground, you will see that it is a valid syntax.
{
"#id": "http://me.markus-lanthaler.com/",
"#type": [
"http://schema.org/Person",
"http://xmlns.com/foaf/0.1/Person"
]
}
However, if you try to move this definition into #context, and apply it to a specific property, you will get an error from the parser. Check it here.
{
"#context": {
"some_property": {
"#id": "http://me.markus-lanthaler.com/",
"#type": [
"http://schema.org/Person",
"http://xmlns.com/foaf/0.1/Person"
]
}
},
"some_property": "value"
}
The error displayed is:
jsonld.SyntaxError: Invalid JSON-LD syntax; an #context #type value must be a string.
I read the documentation carefully and it says that you can define multiple types for node types, but not for value objects.
The documentation clearly says that when #value and #type are used in the same dictionary, the #type keyword is expressing a value type. Otherwise, the #type keyword is expressing a node type.
But here is another example showing that this might not be true.
Does anybody have an idea how to define multiple node types in #context?
You cannot, because you cannot define node types in a context at all.
Starting normatively. In https://www.w3.org/TR/json-ld11/#context-definitions we read:
If the expanded term definition contains the #type keyword, its value MUST be an absolute IRI, a compact IRI, a term, null, or one of the keywords #id, #json, #none, or #vocab.
No arrays allowed here. Because #type in an expanded term definition in a context is used to specify the type of values of the defined property. As mentioned eg. in https://www.w3.org/TR/json-ld11/#typed-values:
Typed values may be expressed in JSON-LD in three ways:
By utilizing the #type keyword when defining a term within an #context section.
Finally let's see what your example expands to if we correct it to have a string value for #type.
{
"#context": {
"some_property": {
"#id": "http://me.markus-lanthaler.com/",
"#type": "http://schema.org/Person"
}
},
"some_property": "value"
}
expands to
[
{
"http://me.markus-lanthaler.com/": [
{
"#type": "http://schema.org/Person",
"#value": "value"
}
]
}
]
As you can see there you indeed have #value and #type together.

qooxdoo: Enhance property to distinguish 0 from -0

Is there a possibility to "override" the equality check of the generated property setters?
I like to have a (integer) property that can distinguish 0 (zero) from -0 (negative zero).
For example this:
qx.Class.define("io.Dummy",
{
extend : qx.core.Object,
properties :
{
value : {
check : "Integer",
nullable : true,
init : null,
event : "changeValue"
}
}
});
so that following code will fire 3 events (instead of only 1):
var dummy = new infodesk.Dummy();
dummy.addListener("changeValue", function (e) {
this.info("changed!");
}, this);
dummy.setValue(-0); // <= changed!
dummy.setValue(-0);
dummy.setValue(+0); // <= changed!
dummy.setValue(+0);
dummy.setValue(-0); // <= changed!
dummy.setValue(-0);
When I "patch" the equality-checks in the framework (qx.core.Property's __emitXxx methods) by replacing code like "if (a===b)" with "if(Object.is(a,b))"[1] it works,
...but it would be nice if there's a nicer -more clean- way of doing this.
Maybe this is a feature request?
For a property definition attribute like "compare" (Function) or "altCheck" (Boolean)?
properties :
{
value : {
check : "Integer",
nullable : true,
init : null,
event : "changeValue",
altCheck : true // 'alternative check enabled'
// rsp.:
compare : function (a, b) { return Object.is(a, b); }
}
}
[1] ECMA-Script 6
As qooxdoo does not offer the functionality of defining a custom value comparer, please open an issue at the github issue tracker at https://github.com/qooxdoo/qooxdoo/ .
I think the idea of having a compare attribute which allows to define a custom comparer is a good idea. If the compare attribute is omitted, the default comparer should be used.
The best way of getting the functionality you need into qooxdoo is to create a pull request which implements the feature, accompanied by unit tests.
I copied the code you mentioned above and found that "changeValue" event happened only once, not 3 times! I use Qooxdoo Playground v5.0.1, Firefox 47.0, Win7.
What's wrong?
You can solve the problem by using the transform key of qooxdoo property, saving the data as string instead of an integer.

MongoDB - Pull from array of objects

I have a collection
{
"_id" : ObjectId("534bae30bf5049a522e502fe"),
"data" : [
{
"0" : {
"content" : "1",
"type" : "text",
"ident" : true
},
"1" : {
"content" : "",
"type" : "text",
"ident" : false
}
},
{
"0" : {
"content" : "2",
"type" : "text",
"ident" : true
},
"1" : {
"content" : "",
"type" : "text"
}
}
]
}
content is unique.
How would i remove the object that matches content: '2'?
I have tried this:
data:{$pull:{"content": deletions[i]}}
where deletions [i] is the content.
and several variations, but i can not get it to work. What am I missing?
As per you comment, you should be worried. I have seen this a few times particularly with PHP applications ( and PHP has this funny kind of notation in dumping arrays ).
The problem is the elements such as the "0" and "1" create sub-documents in themselves, and as opposed to just leaving everything under that structure as the sub-document in itself as the the array member then you run into a problem with accessing individual members of the array as the paths used need to be "absolute".
So this actually "forces" no other possible option to access the elements by what would be the equivalent "dot notation" form. Except in this case it's not just the "nth" element of the array, but the actual path you need to address.
But if this does actually work for you, and it does seem like "someone" was trying to avoid
the problems with positional updates under "nested" arrays ( see the positional $ operator documentation for details ) then you update can be performed like this:
The basic statement is as follows:
db.collection.update(
{
"data.0.context": 2
},
{
"$pull": { "data.$.0.context": 2 }
}
)
That does "seem" to be a bit of a funny way to write this, but on investigating the actual structure you have then you should be able to see the reasons why this is needed. Essentially this meets the requirements of using the positional $ operator to indicate the index of the first matched element in the array ( aka "data" ) and then uses the standard sub-document notation in order to specify the path to the element to be updated.
So of course this poses a problem if the element is actually in an unknown position. But the thing to consider is which usage of the array is actually important to you given the documented limitation? If yo need to match the position of the "inner" element, then change the structure to put the arrays in there.
But always understand the effects of the limitation, and try to model according to what the engine can actually do.

How to describe the predicate/edge of a triple in JSON-LD?

I am new to JSON-LD and LOD so please excuse my use of terminology. I am working on creating a data model in JSON-LD to describe aggregated digital collections based on the European Data Model (http://pro.europeana.eu/edm-documentation).
I would like to create an #context area that describes the relationship:
ore:Aggregation --- edm:aggregatedCHO --> edm:ProvidedCHO
(where 'edm:aggregatedCHO' is the predicate/edge), but I would like to label edm:ProvidedCHO as 'sourceResource' in my model.
Currently my #context looks something like this:
{
"#context": {
"edm" : "http://www.europeana.eu/schemas/edm/",
"sourceResource" : {
"#id" : "edm:ProvidedCHO",
"#type" : "edm:aggregatedCHO"
}
}
}
My intention was to define the predicate ('edge') using #type, and the node contents using #id, but after reviewing the W3C Recommendation, this seems incorrect, and that 'edm:ProvidedCHO' should actually be the #type, because it describes the content type of the node (http://www.w3.org/TR/json-ld/#typed-values).
My question, generally, is where/how do you include the predicate of a triple in a JSON-LD #context statement?
In this case specifically, how do I represent a node called 'sourceResource' that contains edm:ProvidedCHO objects that are each an edm:aggregatedCHO?
Note that setting #type in the context says that the term is expected to be a literal with that datatype; you probably want to use this #type in the body, which will create a type edge, if you will.
Note that the #context does not define relationships, but terms, and how the values of the terms should be interpreted (along with a couple of other things). I think what you want is to have an #context that simply defines terms you want to use in the body of the JSON, where you can define your nodes and they're relationships.
This might be something like the following:
{
"#context": {
"edm" : "http://www.europeana.eu/schemas/edm/",
"ore": "http://example/",
"edm:aggregatedCHO": {"#type": "#id"}
},
"#id": "ore:Aggregation",
"edm:aggregatedCHO": "edm:ProvidedCHO"
}
It's always good to test your JSON-LD on the JSON-LD playground, or some similar service or tool.

MongoDB Index Array only partly working

I know there is already a lot on this subject out there, but none of the questions do help me going on.
I have a File-Upload-System via GridFS which generates documents like this:
{ "_id" : ObjectId( "4f3723607b5c0b8d01060000" ),
"filename" : "7326_150970547928_746052928_2521002_2164327_n.jpg",
"filetype" : "image/jpeg",
"title" : "Indexed File 1",
"author" : "chewbacca",
"document" : "Rechnungen",
"keywords" : { "0" : "Darth",
"1" : "Vader",
"2" : "Haut",
"5" : "Putz",
"6" : "Pushy" },
"uploadDate" : Date( 1329013600519 ),
"length" : 61423,
"chunkSize" : 262144,
"md5" : "c73cce0bb6f349007635751f9a1a7ddd" }
As you can see I have a field 'keywords' which is an array of keywords.
I want to build a search-option to search this field comparable to a fulltext search.
Therefor I indexed the field 'keywords' seperately.
db.fs.files.ensureIndex({ keywords : 1 })
Now the problem is, that this works sometimes. Or to say yesterday it worked on some files, but on some it won't find anything.
Assuming I did the Indexing like above, I would think that
> db.fs.files.find({keywords : "Vader"})
would give me the document printed above. Or am I missing something??
(My only explanation why this could be, is: it takes a lot of time to create indexes and it ain't ready yet, which is practically impossible right, or that there is some problem with the options 'background', 'dropDups', 'unique' etc...
I tried everything. I dropped the Indexes with;
> db.fs.files.dropIndexes()
And created them again. Always controlling via
> db.fs.files.getIndexes()
But no, I can't get any results...
I also tried to make the indexing via PHP just after I saved the file in the database.
For that I use the following code:
$gridFS->ensureIndex(array('keywords' => 1), array("unique" => true));
Or also without the unique option.
As I said sometimes this works and I can query the keywords, but sometimes I can't. Or some keywords are found, but those of other documents not.
Could it be that indexes ain't made for every document equally???
Please somebody help me on that, I really don't get the issue here!
Thanks already.
I suggest you to use a true array in the keywords:
"keywords" : ["Darth", "Vader", "Haut", "Putz", "Pushy"],
So, the following is expected to work:
db.fs.files.ensureIndex({ keywords : 1 })
db.fs.files.find({keywords : "Vader"})

Resources