Question

Let's say that I have metal material in db that have property Yield strength which can go from 300 to 500 MPa. How can i enter that as literal value.

Should I put 2 properties like YieldStrengthMin and YieldStrengthMax, or it can be done in single entry and formatted something like 300 - 500. I know that I can put it like that as a string type, but what I need is that when I SPARQL my db, I should make query that will find all materials that have let's say YieldStrength > 350. If it's in that interval even partial it should be a valid result.

OK, another example to clarify

I will have db of materials and each type of material have many properties. Let's say prop:hasMeltingTemperature.

material:ZA-12 prop:hasMeltingTemperature    "380 - 430".

material:Zn    prop:hasMeltingTemperature    "420".

Some of them (clean materials) will have one melting temp, and temp of alloys will vary depending of percent of some components.

My application will have to get all materials from db that have let's say melting temperature > 400. So in this case it should get both of them.

And if I query that i need all materials that have melting temp < 425 it should take both of them too. If query is < 400, then only first material.

Anyway, my question is:

Should i make properties like this:

material:ZA-12 prop:hasMeltingTemperature_MIN "380".

material:ZA-12 prop:hasMeltingTemperature_MAX "430".

material:Zn    prop:hasMeltingTemperature     "420".

then when I query I have to detect ">" then compare it to "MIN" temp and "solo" temp, and if it's "<" then compare it to "MAX" temp and "solo" temp.

In this case I have to first detect does material have only "one" or "min-max" temp or "none" temp property.

OR

I can do it something like in the first example and have only one property like:

material:ZA-12 prop:hasMeltingTemperature "380 - 430".

material:Zn    prop:hasMeltingTemperature "420" .

and make some kind of sparql query that could understand "intervals" and compare them?

That's what I was wondering because there are many properties of materials, and many materials, and some of them have "min max" value, some "solo" value, and some don't have that property at all, but have another one with the same problem...

My application will be in php so i will have to generate sparql query in php, so that's why i was looking for some "universal" type of query (checking only one property)..

So my problem is more how to efficiently sparql query it, what's better choice of that 2 for storing data, and how to query it'

Était-ce utile?

La solution

There a few different things that you could mean here. You could

  1. declare that the range of a property is a value within some range;
  2. assert that for some particular individual, its values of a particular property are within some range;

Given that you said that:

what i need is that when i SPARQL my db, i should make query that will find all materials that have let's say YieldStrength > 350. If it's in that interval even partial it should be a valid result.

Using two properties

I think that your best best is to use two properties (e.g., minStrength/maxStrength). This means that you can have data like:

metal72 minStrength 200 ;
        maxStrength 400 .

Then you can write a query with a pattern like

?metal minStrength ?min ;
       maxStrength ?max .
filter( ?min <= 350 && 350 <= ?max )

I think this most closely matches the idea you're trying to capture, because it sounds like each metal is actual associated with some range of values. Where some metals can have exact values (and not a range), you can still use this approach, by putting in your data:

Zn minStrength 420 ;
   maxStrength 420 .

Then all of your metals are consistent (they all have a min value and a max value), and your queries won't have to worry about different cases.

Using ranges, and querying the RDF serialization of the OWL

Now, while I think that the previous approach makes more sense, you can represent data ranges in OWL. For instance, if there's a hasStrength property, you could say that some metal has strengths only within some range by using a restriction like

metal72 a (hasStrength only int[>=200,<=400])

In Protégé this looks like:

restriction in Protege

What this actually means though is not that the metal has some strength range, but that for any triple of the form metal72 hasStrength x, the value of x must be an int in the range [200,400], or else the data is inconsistent. This is obviously different than saying that the metal has a strength range.

The OWL ontology can be serialized in RDF, and then you can query the RDF using SPARQL. You'll need to know what the RDF looks like though. In this case, it's:

:metal72  a     owl:NamedIndividual , :Metal ;
        a       [ a                  owl:Restriction ;
                  owl:allValuesFrom  [ a                     rdfs:Datatype ;
                                       owl:onDatatype        xsd:int ;
                                       owl:withRestrictions  ( [ xsd:minInclusive
                                                         200 ] [ xsd:maxInclusive
                                                         400 ] )
                                     ] ;
                  owl:onProperty     :hasStrength
                ] .

That's a bit much, but you can query against it with SPARQL with a query like the following. It will return any ?metal which has a type hasStrength only int[>=min,<=max], where min ≤ 350 ≤ max.

prefix metal: <http://www.example.org/metal#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?metal where { 
  ?metal a metal:Metal ;
         a [ owl:allValuesFrom [ owl:withRestrictions [ rdf:rest* [ xsd:minInclusive ?min ] ] ;
                                                      [ rdf:rest* [ xsd:maxInclusive ?max ] ] ] ;
             owl:onProperty metal:hasStrength ] .
  filter( ?min <= 350 && 350 <= ?max ) 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top