Projections - Search

Endpoint : POST - /projection/find
Payload :
"query" : ,
"edge" : true,
"view" :

Content-Type:
- "text/turtle" (Receive the data serialized into Turtle)
- "application/json" (Receive the data serialized in JSON)

Greetings sir, this is the page reserved for Projection research using the API /projections/find entry.
Before everything else, note that this API is in progress and wif you see something really important is missing please feel free to tell us ! (About right here will be a link or a button to launch issue on our gitlab, i want to believe)

The query DSL (Domain Specific Language) is basically the same as the one used in MongoDB to search data (In case you want to check their documentation : https://docs.mongodb.com/manual/reference/operator/query/). It is expected to be a JSON payload respecting the following template (as described above) :



"query" : ,
"edge" : true,
"view" :

About the template:

  • query : The actual query to use to filter the projections, we will define this in the next section
  • edge : Ask Philippe to know how to use that
  • view : Precise the data you want to be returned (see View section)

If you are not familiar with the semantic world, i highly suggest you to read the following section. It may be a bit dense but trust me, it is worth it.

http://ziggy-wiki-dev.nprpaas.ddns.integ.dns-orange.fr/#The%20semantic%20world%20in%20Easy%20Mode

http://ziggy-wiki-dev.nprpaas.ddns.integ.dns-orange.fr/#How%20to%20read%20an%20ontology

Filtering projections

To filter projections you have several ways

  • Class
  • IRI
  • RWID
  • Datatype property (Attributes)
  • Object property (Edges)

And you should be able to combine pretty much all of them.

Class

As you could understand from the previous sections (you DID read them, right ?), projections in Thing’in are defined using class from ontologies. We defined an operator for that purpose : $class. You may use it the same way you would do in MongoDB, all you need is the IRI of the class you want to use as a filter.

Ask for projections on a single class



"$class" : "https://w3id.org/saref#Sensor"

Ask for projections on a single class with inheritance enabled



"$class" : "$eq" :
"https://w3id.org/saref#Sensor",
"$inheritance" : true


Ask for projections within a set of class (don’t ask me why would someone want both sensor and washing machines)

{
   "$class" : {
       "$in" : [ "https://w3id.org/saref#Sensor", "https://w3id.org/saref#WashingMachine"]
   }
}

Ask for projections within a set of class with inheritance

{
   "$class" : {
       "$in" : [ "https://w3id.org/saref#Sensor", "https://w3id.org/saref#WashingMachine"]
   },
   "$inheritance" : true
}

The same also works with the $nin operator. Ask for projections which are not in a set of class

{
   "$class" : {
       "$nin" : [ "https://w3id.org/saref#Sensor", "https://w3id.org/saref#WashingMachine"]
    },
   "$inheritance" : true
}

The "$not" operator is not implement yet for a single class, i do apologize.

IRI

Each projections have their specifically assigned IRI, to perform filtering on the IRI we created the $ori operator...
Wait, What ? Why not $iri ? Rofl, that guy just made a spelling mistake in the documentation. No, it is ori in our code which stands for Ontology Resource Identifier ( you made the same spelling mistake in every part of your code ? oO). There is some story behind this and hopefully you will be given answers when the rework on the namespaces will be finished. Anyway, this is to make filter based on individual IRI.

So, about, the $ori operator, you have the same kind of expressivity than with the $class operator.

Ask for projections with the given IRI

{
   "$ori" : "http://orange-labs.fr/fog/ont/transport.owl#AnIndividual"
}

Ask for projections within the given set of IRI

{
   "$ori" : {
       "$in" : [ "http://orange-labs.fr/fog/ont/transport.owl#AnIndividual", "http://orange-labs.fr/fog/ont/transport.owl#AnOtherIndividual" ]
   }
}

Ask for projections which are not within the given set of IRI

{
   "$ori" : {
       "$nin" : [ "http://orange-labs.fr/fog/ont/transport.owl#AnIndividual", "http://orange-labs.fr/fog/ont/transport.owl#AnOtherIndividual" ]
   }
}

Ask for projections with the ori respecting a given regular expression

NOT IMPLEMENTED YET ¯\_(ツ)_/¯

RWID

RWID stands for Real World IDentifier. The goal of RWID is to enable aggregation of projection based on a specific field which would hold a key able to identify it uniquely in a world wide point of view.
As an example, a MAC address is considered as a safely unique data and can be used as a RWID. The goal is to make correlation based on the rwid value and bind together projections which were uncorrelated before even if they are from separated namespaces. As a logical consequence, the $rwid operator automatically removes the namespaces barrier.
The operator is $rwid, note that RWID may only store strings and for that reason the amount of operator are limited just as the same as the ones from $class or $ori.

Ask for projections with the given RWID

{
   "$rwid" : "so:me:ad:dr:es:mac"
}

Ask for projections within the given set of RWID

{
   "$rwid" : {
       "$in" : [ "so:me:ad:dr:es:mac", "a_unique_value_related_to_the_real_world" ]
   }
}

Ask for projections which are not within the given set of RWID

{
   "$rwid" : {
       "$nin" : [ "so:me:ad:dr:es:mac", "a_unique_value_related_to_the_real_world" ]
   }
}

Ask for projections with the RWID respecting a given regular expression

NOT IMPLEMENTED YET ¯\_(ツ)_/¯

Datatype property

Datatype property as we explained before are the attributes of our projections so, basically, i you need to perform a find on projection where the datatype property, say "weight", is greater or equal to 10, the expected query is the following :

{
   "weight" : {  "$gte" : 13.5 }
}

Just like in MongoDB where you set the field which you want to filter, you may set the datatype property as a key of the query payload and then assign the requested filter. About the right name of the datatype property, you do not want to use the IRI of the datatype_property. If you do something like that:

{
   "http://orange-labs.fr/fog/ont/transport.owl#weight" : {  "$gte" : 13.5 } <-- DOES NOT WORK
}

It will not work. To make things quick, in the case of Datatype property and Object property IRIs are directly used in the data model of the graph. However IRIs can not be used directly as the label of an edge or an attribute because they holds special character which are not allowed by OrientDB (Ascii only, unfortunately...) As a workaround, we implemented a simple formatting strategy which replaces the special characters of an IRI by _ and we take only the last 3 bloc separated by _.

{
   "http://orange-labs.fr/fog/ont/transport.owl#weight" : {  "$gte" : 13.5 } <-- DOES NOT WORK
   "ont_transport_owl_weight" : {  "$gte" : 13.5 } <-- MUCH BETTER
}

I do agree this is not really handy, but this allows you to take the serialized datatype properties iri from the JSON output and apply them directly to the query payload. For any datatype property, here is the list of the available operators:

  • $gt
  • $gte
  • $lt
  • $lte
  • $eq
  • $ne
  • $in
  • $nin
  • $geoWithin-* -*
  • $nearSphere-* -*
    • See Geospatial Operators

When you give a query with this form :

{
   "namespace_ontology_owl_weight" : 13.5
}

Thing’in will implicitely interpret this as a an $eq clause :

{
   "namespace_ontology_owl_weight" : { "$eq" : 13.5 }
}

If you want to precise an operator different from the equality, you may do like in the example above :

{
   "namespace_ontology_owl_weight" : { "$lt" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$lte" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$gt" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$gte" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$eq" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$ne" : 13.5 }
}
{
   "namespace_ontology_owl_weight" : { "$in" : [ 13.5, 23.7] }
}
{
   "namespace_ontology_owl_weight" : { "$nin" : [ 13.5, 23.7] }
}

JSON uses double for decimal number representation, since datatype properties for float and double are both stored as double into OrientDB (easier to handle data that way), there is no lack of precision using JSON.
If you follow strictly the datatypes from JSON to do your research you should not encounter any trouble.

About the query output datatype, nonetheless it will decide if the found projections will be serialized into turtle or JSON, it also trigger or not datatype checking.
When running the projection find query with text/turle as output, before running the query against the database each datatype properties, on which filter are performed, will be checked to verify if the given value datatype is sane.

An example :
Assuming that the range of the datatype property is http://random/namespace/ontology.owl#weight xsd:float, the following query :

{
   "namespace_ontology_owl_weight" : { "$nin" : [ "AZERTY", true] }
}

Will return to you an error because you are performing a search against a datatype property using the wrong datatype.
It adds a little overhead to execute the query but at least you will be sure you are correctly manipulating your data, OrientDB uses some implicit conversion and may accept to do equality between string, integer, boolean (i do not have the exact list, but there are some possibilities) but in the
end, most of the time it is irrelevant. You may retrieve data which should have never been returned and even worse, data that should have been returned will be kept silent.

### GeoSpatial Operators
The available GeoSpatial operators are the following :
- $geoWithin
- $nearSphere

GeoSpatial operators are special, they need to be backed up by a GeoJson Spatial Aspect. Aspect are behaviors that can be configured above the ontologies concept, their main goal is to optimize the data to enforce their potential. GeoJson Spatial Aspect do exactly that, they build additionnal
geo index over the targeted datatype property and enable the use specific geographic function in the queries. You might want more information about the aspect here : http://ziggy-wiki-dev.nprpaas.ddns.integ.dns-orange.fr/#Projections%20-%20Aspects.

GeoSpatial Operators works using the GeoJson standard : http://geojson.org/.
We do not make use of feature, we only want the "geometry" part, using the GeoJson standard, if you want to declare a geometry point you will declare something like this :

{
   "type":"Feature",
   "geometry":{
       "type":"Point",
       "coordinates":[125.6,10.1]
   }
}

We will ask a bit less of data, give us this :

# About the way view work. (TBD, ask Philippe)

{
   "type" : "Point",
   "coordinates" : [LONGITUDE-* , LATITUDE-* ]
}

ABOUT THE COORDINATES : note the order of longitude, latitude in the coordinates array. This is important because if you take coordinates from google their order is [ LATITUDE, LONGITUDE ]. The engine of OrientDB is designed to work with LONGITUDE, LATITUDE and the GeoJSON standard also
works that day, we will follow their path.

Let’s say you want all projection with GeoJson Point located into the given polygon :

{
   "type" : "Polygon",
   "coordinates" : [[[120.0,8.0], [120.0,12.0], [130.0,12.0], [130.0,8.0]]]
}

Using JSON for the output you will have the following query :

{
   "www_opengis_net_gml_pos" : {
       "$geoWithin" : {
           "$geometry" : {
               "type" : "Polygon",
               "coordinates" : [[[120.0,8.0], [120.0,12.0], [130.0,12.0], [130.0,8.0]]]
           }
       }
   }
}

And for Turtle :

{
   "http://www.opengis.net/gml/pos" : {
       "$geoWithin" : {
           "$geometry" : {
               "type" : "Polygon",
               "coordinates" : [[[120.0,8.0], [120.0,12.0], [130.0,12.0], [130.0,8.0]]]
           }
       }
   }
}

Since those are filtering operators you may combine them with other filtering operators:

{
   "$and" : [
       {
           "$class" : {
               "$in" : [ "http://random/namespace/ontology.owl#sensor", "http://random/namespace/ontology.owl#device" ],
               "$inheritance" : true
           }
       },
       {
           "namespace_ontology_owl_weight" : {  "$gte" : 13.5 }
       },
       {
           "http://www.opengis.net/gml/pos" : {
               "$geoWithin" : {
                   "$geometry" : {
                       "type" : "Polygon",
                       "coordinates" : [[[120.0,8.0], [120.0,12.0], [130.0,12.0], [130.0,8.0]]]
                   }
               }
           }
       }
   ]
}

Note the number of nested arrays to describe the polygon, this is not a mistake, (if it does not work that way go back to only 2 level [ [ long1, lat1 ], [long2, lat2] ] and open an issue on the forge please.) The third array is needed to describe "rings", if we take for example
the Pentagon (the building in the USA), this is a large building with a hole in its center. Having multiple "rings" allows you to give a list for the "outer" ring to describe the exterior of the building, and an "inner" ring to describe the interior of the building.

At last the $nearSphere operator:

{
   "http://www.opengis.net/gml/pos" : {
       "$nearSphere" : {
           "$geometry" : {
               "type" : "Point",
               "coordinates" : [125.6,10.1]
           },
           "$maxDistance" : 5000
       }
   }
}

The $nearSphere operator expect a Point into the geometry and will only works on datatype properties storing GeoJson point (OrientDB limitation). You need to set the maximum distance allowed for the research with the "$maxDistance" specific inner operator, the value are meters.
There will be in the future a "$minDistance" operator added.

Note that there may be a lack of precision using $nearSphere because it works with a spheric representation of the earth instead of a geoid. It goes much faster but it doesn’t take into account the gradual deformation of the earth in high latitude and it leads to potentially location
error of several kilometers. Again, we can’t do much about that for the moment, sorry for the inconvenience.

View

As client, in a nominal case, does not want all the data properties attached to an object/node, we put in place a selector. If the clause view contains attributes name, only these attributes should be presented in the response.

"view" : {
 "name" : true,
 "age" : true
}

With the previous example, only the data properties "name" and "age" will be present in the object attributes response. Note that the "_uuid" attribute will be always returned.

Moreover to ease the work of the developpers in terms of mapping name between the attribute name inside the database and the attribute name that he wants, we propose a rewrite mechanism.

"view" : {
 "name" : "nom",
 "age" : true
}

With the previous example, the data properties "name" will be rename by "nom" in the object attributes response.

Object property

Object properties are a bit more complex to handle as they introduce sub queries and graph patten, but hopefully you’re reading the documentation so let’s go through it :). To do a research by object properties you will have to declare a graph pattern, a graph pattern is a set of vertices and edges. Each vertex will be a projection defined in a JsonObject while the object property (which will be the edge) will be defined inside the vertex prefixed by ->.

Consider the following query :

[ {
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Room",
       "$inheritance" : true
   },
   "->ontologies_dogont_owl_isIn" : { "$alias" : "building" }
},
{
"$alias" : "building",
"$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Building",
       "$inheritance" : true
   }
} ]

It looks like this in a full find projection payload :

{
   "query" : [ {
       "$class" : {
           "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Room",
           "$inheritance" : true
       },
       "->ontologies_dogont_owl_isIn" : { "$alias" : "building" }
   },
   {
   "$alias" : "building",
   "$class" : {
           "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Building",
           "$inheritance" : true
       }
   } ],
   "edge": true,
   "view": {}
}

Aliases

Before anything else, the query here is a JSON Array with two elements, both can be seen as sub queries which you would do in a classic relationnal environment:
- Projection instance of #Room or its children
- Projection instance of #Building or its children

We make use of dereferencing, the first element is targeting the second one with the ontologies_dogont_owl_isIn object property using the "building" alias. This is our "join" if you refer to the relationnal world. If you think about it, making joins in SQL is very much like declaring some graph pattern. In human language this query means : "give me all the instances of Room and subclasses of Room which are connected with the object property ontologies_dogont_owl_isIn edge to instances of Building and subclasses of Building". Speaking of graph pattern, it look like this :

Room -ontologies_dogont_owl_isIn-> Building

The alias system allows you to declare complex graph pattern such as (A -> B && B -> C && A -> C ), you can also make circular pattern (A -> B && B -> C && C -> A). About the alias, those must be composed only of string. There is a simple rule to apply, every vertex targeted by an object property must have its own alias.

The syntax is a bit heavy ? I like my readers so i thought of you, here is the same with a contracted form :

[ {
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Room",
       "$inheritance" : true
   },
   "->ontologies_dogont_owl_isIn" : "building"
},
{
"$alias" : "building",
"$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Building",
       "$inheritance" : true
   }
} ]

If you want something of the form ( A -> B && A -> C ) using the same object property, use a JSON Array :

[ {
   "->foaf_0_1_knows" : [ "alice", "bob" ]
},
{
   "$alias" : "alice"
},
{
   "$alias" : "bob"
} ]

Object property depth & recursivity

As you can guess from the examples above, the syntax to set an object property is something like this :

->my_object_property : "alias_as_a_string"

Now that is somekind of cool but what about depth and recursivity ? Deep traversals making use of infinite recursivity is not possible yet (believe it or not, the graph database does not detect graph cycle and runs forever when performing traversals with infinite depth...), but you may perform traversals with reasonnable level of depths (reasonnable if you want the query to returns something before it times out).

->my_object_property : {
   "$alias" : "alias_as_a_string",
   "$maxDepth" : 3
}

With this configuration, you tell Thing’in to repeat up to 3 time the edge "my_object_property" to match the pattern. Now that’s great but sometimes you don’t want the first iteration, you only want to retrieve the data after a certain depth. The classic example about this is getting the friends of the friend. To do so there is the "$minDepth" operator which enables you to precise the minimal depth from which you want to retrieve data :

[ {
   "$ori" : "http://orange-labs.fr/fog/ont/iot.owl#A",
   "->foaf_0_1_knows" : { "$alias" : "people", "$minDepth" : 2, "$maxDepth" : 3 }
},
{
   "$alias" : "people"
} ]

If you run the query on a dataset with the following form :

A -> B
A -> C
B -> D
B -> E
C -> F
C -> G

The query will return you D, E, F, G as they are the only projections with the minimal acceptable depth. Note that you can’t set $minDepth without setting $maxDepth. $minDepth is not the solution to everything and depending on the structure of your graph it will not be sufficient, let’s add a simple relation to the dataset up ahead:

A -> B
A -> C
B -> D
B -> E
C -> F
C -> G
{{B -> A}}

The same query will now return D, E, F, G and A because there is an object property which allows the graph traversal to go back to the origin point. Here the depth operator will not help you, you must use $excludeSelf:

[ {
   "$ori" : "http://orange-labs.fr/fog/ont/iot.owl#A",
   "->foaf_0_1_knows" : { "$alias" : "people", "$minDepth" : 2, "$maxDepth" : 3, "$excludeSelf" : true }
},
{
   "$alias" : "people"
} ]

It adds a constraint on the graph and blocks the starting node to being returned, you will go back to the D, E, F and G result set. Finally, you have the right to mix the contracted form with the complex one :

[ {
   "->foaf_0_1_knows" : [ { "$alias" : "alice", "$maxDepth" : 3 }, "bob" ]
},
{
   "$alias" : "alice"
},
{
   "$alias" : "bob"
} ]

In plain old human language : "Find a projection linked to Bob through a direct foaf_0_1_knows edge and linked to alice through at most 3 foaf_0_1_knows edges".

Complex patterns

Since every block into the JsonArray is a projection queryall by itself, described into a JsonObject, you can mix everything you read before in this documentation with the object properties.

[ {
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Room",
       "$inheritance" : true
   },
   "->ontologies_dogont_owl_isIn" : "building"
},
{
   "$alias" : "building",
   "$class" : {
           "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Building",
           "$inheritance" : true
       },
   "ontologies_dogont_owl_name" : {  "$in" : ["Orange Gardens - Batiment 3A", "Orange Gardens - Batiment 3B"] }
} ]

In human language it means : "give me all the instances of Room and subclasses of Room which are connected with the object property ontologies_dogont_owl_isIn edge to instances of Building and subclasses of Building which are named Orange Gardens - Batiment 3A or Orange Gardens - Batiment 3B ".
The good thing is, we are not in the relationnal world, joins does not scares us, you want to declare a really precise pattern ? Go on, Impress me :

[ {
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Room",
       "$inheritance" : true
   },
   "->ontologies_dogont_owl_adjacent" : "cafet"
   "->ontologies_dogont_owl_isIn" : "og"
}, {
   "$alias" : "og",
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Building",
       "$inheritance" : true
   },
   "ontologies_dogont_owl_name" : {  "$in" : ["Orange Gardens - Batiment 3A", "Orange Gardens - Batiment 3B"] }
   "->ontologies_dogont_owl_isIn" : "town"
}, {
   "$alias" : "town",
   "$class" : {
       "$eq" : "http://orange-labs.fr/fog/ont/flexoffice.owl#Town",
       "$inheritance" : true
   },
   "ontologies_dogont_owl_name" : "Paris"
}, {
   "$alias" : "cafet",
   "$class" : {
       "$eq" : "http://elite.polito.it/ontologies/dogont.owl#Cafetaria",
       "$inheritance" : true
   }
} ]

(I currently pray the almighty lord that you will never run this query)
Using graph pattern, it would looks like this :

<<<
Room -ontologies_dogont_owl_isIn-> Building -ontologies_dogont_owl_isIn-> Town
Room -ontologies_dogont_owl_adjacent-> Cafetaria
<<<

For lisibility’s sake i hid the local clauses to each node but you have the general idea. Note that even though i used the $class operator everywhere, you don’t have to the exact same thing, if all you want is to have a projection which is connected to another projection using a specific object property, don’t mind me go for it !

[ {
   "->ontologies_dogont_owl_isIn" : "a"
},
{
   "$alias" : "a"
} ]

This is a very concise, generic, query. Here you are asking for every projections which are connected to an other projections using the ontologies_dogont_owl_isIn object property. This is correct.
There are still two things to you need to know before i leave you (or before you leave me, consider it the way you want :)).

Handling namespaces

Namespaces have yet to be reworked and unfortunately due to our lack of time and some emergency, it will probably stay that way until january. Still we already implemented tools to allow you to describe linked projections accross multiple namespaces. If you take the query right above you will have to define a global namespace for this query, say the namespace "THING_IN_IS_AWESOME", if you run the query with no further adjustements Thing’in will give you back only the projections linked with a ontologies_dogont_owl_isIn object property within the "THING_IN_IS_AWESOME" namespace.

You want now projection linked with the same object property but from the "THING_IN_IS_AWESOME" namespace to the "THING_IN_SOMETIMES_FAILS" namespace, you can do so but you need to override the global namespace in a projection local level:

[ {
   "->ontologies_dogont_owl_isIn" : "a"
},
{
   "$alias" : "a"
   "$namespace" : "THING_IN_SOMETIMES_FAILS"
} ]

The query is the same but now projection with the "a" alias will be taken from the "THING_IN_SOMETIMES_FAILS" namespace, By the way, "$namespace" is a bit heavy so you can use this contracted form (i told you i like you guys :)):

[ {
   "->ontologies_dogont_owl_isIn" : "a"
},
{
   "$alias" : "a"
   "$ns" : "THING_IN_SOMETIMES_FAILS"
} ]

Returning data

Finally, some people asked us about some way to declare precisely the data they wanted to retrieve from the query. We did some adjustements and now a find query returns everything matched into the graph pattern by default. Although the system is not as expressive as what we want him to be, you can now configure what you want to retrieve projections based on the aliases, if you take the query right above, and do the following payload :

{
   "query" : [ {
       "->ontologies_dogont_owl_isIn" : "a"
   },
   {
       "$alias" : "a"
       "$ns" : "THING_IN_SOMETIMES_FAILS"
   } ],
   {{"return" : "a"}},
   "edge": true,
   "view": {}
}

The query will return only the projections with the "a" alias. Unfortunately, this is the limitation we are working on, you can only use one alias. If you try the next query :

{
   "query" : [ {
       "$alias" : "b"
       "->ontologies_dogont_owl_isIn" : "a"
   },
   {
       "$alias" : "a"
       "$ns" : "THING_IN_SOMETIMES_FAILS"
   } ],
   {{"return" : [ "a", "b"]}},
   "edge": true,
   "view": {}
}

This will NOT work. And I dare say that it’s not about writing a parser able to take a JSON Array or a single list into parameters. OrientDB doesn’t seems to have the right operator yet to do that kind of thing, which is kind of problematic i know, it may be added in the next version but we don’t have much info right now. Still, if you want to force and make all the data are returned (default behavior), you can use the $all argument:

{
   "query" : [ {
       "$alias" : "b"
       "->ontologies_dogont_owl_isIn" : "a"
   },
   {
       "$alias" : "a"
       "$ns" : "THING_IN_SOMETIMES_FAILS"
   } ],
   {{"return" : $all}},
   "edge": true,
   "view": {}
}

— -

In conclusion.

Anonymous_reader_1 : Wow, that looks great ! Can i inverse the object property though ? With something like ontologies_dogont_owl_isIn<- ?

Author : Hm, unfortunately there is still some limitations. We can’t do that yet.

Author(After update) : Not available yet...

Anonymous_reader_2 : Do you handle recursivity ? It would be nice to have an operator like >>ontologies_dogont_owl_isIn which does not limit itself to one level of depth

Author : Hm, sorry, not available yet...

Author(After update) : Not available yet... We do have some kind of recursivity and depth handling though ! Go check the $minDepth and $maxDepth operators.

Anonymous_reader_3 : In the case my graph pattern is cyclic, with something like A -> B -> C -> A, do you have a workaround ?

Author : Hee...

Author(After update) : Aha ! Yes we do ! Thanks to the aliases.

Anonymous_reader_4 : I have the same problem as the anonymous_reader_3 but i also want to retrieve A and B, not only A, can we precise which part of the pattern we want to retrieve ?

Author : Hee 2 ...

Author(After update) : Well, as explained above you can either retrieve everything or the single node which you are interested in.

Back to business, there is still a lot of improvements to be made but unless it is really critical (and in that case make sure to contact us ;) ) i will ask you to be patient ... To be fair the Search API was not supposed to be that powerful, it is more the job of SPARQL and we have yet to decided the exact direction we want to take for this API.