This page is a stub and will be completed shortly.
Search and Matchmaking: SPARQL Queries on GoodRelations Data
On this page, we will give examples of querying GoodRelations data in SPARQL.
This page is a stub and will be extended shortly.
Overview: Read this post on the GoodRelations mailing list:
select distinct ?o as ?uri, bif:sprintf("%.2f",?p2) as ?price, ?currency, ?text where
{
# Find products that contain "Johnny Cash"
?s1 rdfs:comment ?text .
?text bif:contains '"Johnny Cash"' .
?s1 a gr:ProductOrServicesSomeInstancesPlaceholder .
# Find offers that include those products
?o a gr:Offering.
{
# The following UNION is because we cannot assume that the expansion of gr:includes is on
{?o gr:includes ?s1.}
UNION
{?o gr:includesObject ?t.
?t a gr:TypeAndQuantityNode.
?t gr:typeOfGood ?s1.}
}
?o gr:hasPriceSpecification ?p.
?p a gr:UnitPriceSpecification.
?p gr:hasCurrency ?currency.
?p gr:hasCurrencyValue ?p2.
} order by desc (?p2) limit 20 offset 0
# Fetch Business Entities & Geo Data
# Note that there are 3 variants of vcard
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?uri ?city ?zip ?country ?lat ?long WHERE
{
?be a gr:BusinessEntity.
?be gr:legalName ?name.
?be foaf:page ?uri.
?be vcard:adr ?adr.
?adr vcard:locality ?city.
?adr vcard:postal-code ?zip.
?adr vcard:country-name ?country.
?be vcard:geo ?geo.
?geo vcard:latitude ?lat.
?geo vcard:longitude ?long.
}
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ceo: <http://www.ebusiness-unibw.org/ontologies/consumerelectronics/v1#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label ?weight ?ean WHERE
{?m a ceo:Camcorder.
?m rdfs:label ?label.
?m ceo:hasWeight ?v.
?v gr:hasValueFloat ?weight.
?v gr:hasUnitOfMeasurement "GRM"^^xsd:string.
OPTIONAL {?m gr:hasEAN_UCC-13 ?ean}
}
ORDER BY ?weight
LIMIT 10
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ceo: <http://www.ebusiness-unibw.org/ontologies/consumerelectronics/v1#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label ?weight ?ean WHERE
{?m a ceo:Camcorder.
?m rdfs:label ?label.
?m ceo:hasWeight ?v.
?v gr:hasValueFloat ?weight.
?v gr:hasUnitOfMeasurement "GRM"^^xsd:string.
OPTIONAL {?m gr:hasEAN_UCC-13 ?ean}
}
ORDER BY ?weight
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ceo: <http://www.ebusiness-unibw.org/ontologies/consumerelectronics/v1#>
SELECT MIN (?w) WHERE
{?m a ceo:Camcorder.
?m ceo:hasWeight ?v.
?v gr:hasValueFloat ?w.
?v gr:hasUnitOfMeasurement "GRM"^^xsd:string.
}
# Find someone who provides a service that contains "manicure" in the description
SELECT ?offer ?uri ?price ?currency WHERE
{
?offer a gr:Offering .
?offer gr:hasBusinessFunction gr:ProvideService .
{
{
?offer gr:includes ?service.}
UNION
{
?offer gr:includesObject ?o .
?o gr:typeOfGood ?service .
}
}
OPTIONAL {?service rdfs:label ?label}
OPTIONAL {?service rdfs:comment ?description}
OPTIONAL {?service foaf:page ?uri}
?offer gr:hasPriceSpecification ?p .
?p a gr:UnitPriceSpecification .
?p gr:hasCurrency ?currency .
?p gr:hasCurrencyValue ?price .
FILTER (regex(?label, "manicure", "i") || regex(?description, "manicure", "i"))
}
(Thanks to Kingsley Idehen for his support!)
# Describe Camera and order results in ASC weight/zoom_factor ratio
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ceo: <http://www.ebusiness-unibw.org/ontologies/consumerelectronics/v1#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?m ?label ?weight ?ean ?zoomfactor (( ?weight / ?zoomfactor )) as ?weight_zoom_factor_ratio
WHERE
{?m a ceo:Camcorder.
?m rdfs:label ?label.
?m ceo:hasWeight ?v.
?m ceo:hasDigitalZoomFactor ?z. ?z gr:hasValueInteger ?zoomfactor . filter ( ?zoomfactor > 0 ) .
?v gr:hasValueFloat ?weight.
?v gr:hasUnitOfMeasurement "GRM"^^xsd:string.
OPTIONAL {?m gr:hasEAN_UCC-13 ?ean}
}
ORDER BY ASC ( ?weight / ?zoomfactor )
# --- DESC Order
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ceo: <http://www.ebusiness-unibw.org/ontologies/consumerelectronics/v1#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?m ?label ?weight ?ean ?zoomfactor (( ?weight / ?zoomfactor )) as ?weight_zoom_factor_ratio
WHERE
{?m a ceo:Camcorder.
?m rdfs:label ?label.
?m ceo:hasWeight ?v.
?m ceo:hasDigitalZoomFactor ?z. ?z gr:hasValueInteger ?zoomfactor . filter ( ?zoomfactor > 0 ) .
?v gr:hasValueFloat ?weight.
?v gr:hasUnitOfMeasurement "GRM"^^xsd:string.
OPTIONAL {?m gr:hasEAN_UCC-13 ?ean}
}
ORDER BY DESC ( ?weight / ?zoomfactor )
Example: Assume we want to buy a toaster.
Step I: Collect Candidate Offers
1. Direct Lexical Search
Select all gr:Offerings that contain *toaster* in their rdfs:label or rdfs:comment or that contain an gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder that contain *toaster* in their rdfs:label or rdfs:comment and are linked to the offering via gr:includesObject or gr:includes. Filter to those with a gr:hasBusinessFunction of "Sell". This set should be added to the result set.
2. Direct Class-based Search
a) Find all subclasses of gr:ProductOrService from relevant products or services ontologies (eClassOWL, freeClass) that contain *toaster* in their rdfs:label or rdfs:comment, maybe restrict to those with lang=en.
b) Find all gr:Offerings that contain an gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder which is an instance of any of the classes from a). Filter to those with a gr:hasBusinessFunction of "Sell".
Important: There can be ontology classes in the space that contain the term "toaster" but not in the sense of a product or service, but e.g. as a topic. Thus, you should constrain your search to those objects that are instances of the respective class AND instances of gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder. When using eClassOWL and freeClassOWL -gen classes, this is automatically the case.
3. Direct Class-based Search, Subsume Match
a) same as #2, but include rdfs:subClasses of the classes found in 2.a) If the repository has a reasoner, this extension will take place automatically, but for ranking purposes, you may still treat the offers found this way differently. Note that there are fundamental differences in the implications of the match type between Web services discovery (from where this term originates) and product search: In WS discovery, if you are looking for a service that delivers tickets and a service is announced to deliver train tickets, you have to check at the instance level whether you can actually use the service for that purpose (i.e. this is a candidate match only - you do not yet know whether you can use that service to actually fulfill your concrete goal). In product search, it is the opposite: If you are looking for someone who sells a beverage, than someone who offers to sell a beer is a correct match.
(Have to double check that, though ;- - MH. I think the modeling of existential quantification via gr:ProductOrServiceSomeInstancesPlaceholder may be a source of this difference.)
Important: There can be ontology classes in the space that contain the term "toaster" but not in the sense of a product or service, but e.g. as a topic. Thus, you should constrain your search to those objects that are instances of the respective class AND instances of gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder. When using eClassOWL and freeClassOWL -gen classes, this is automatically the case.
4. Direct Class-based Search, Plug-in Match
There may be more potentially relevant offers, which are those that include objects that are instances of a superclass of the classes from 2.a). For example, offers to sell "Household Appliances" may be relevant, but are not guaranteed to. This type of match is called "Plug-in".
Approach: Search for superclasses of the classes from 2.a) and repeat step 2b.
The results should be treated differently when you rank / present the results, because that are just candidate matches.
The differences to plug-in matches in service discovery from #3 apply in here, to.
5. Translation and Synonymy
Find all translations in relevant languages and respective synonyms of "toaster" and repeat approaches 1-4. Mind to set the lang tag to the proper language. For example, you can use the wikipedia/dbpedia corpus to find proper translations and wordnet to find synonyms.
6. Lexical Search, Broad Query Expansion
a) Repeat #1 but expand it to any offer that contains, as rdfs:comment or rdfs:label in the gr:Offering or an attached gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder, at least one word (w/o stop words) from the rdfs:label or rdfs:description of all subclasses of classes in products or services ontologies that contain the word "toaster".
b) as a, but also include the words from the rdfs:label from all superclasses up to n levels away.
Step II: Filter and Rank
1. For all gr:ActualProductOrServiceInstance or gr:ProductOrServiceSomeInstancesPlaceholder instances from the candidate set, you can search for the properties (subproperties of
rank them by frequency of usage and use the respective values to filter or rank the results (or ask the user to specify preferences on available features. As for the absence of features, note the discussion in the GoodRelations Technical Report).
2. Use all commercial properties of the gr:Offering for refining / filtering / ranking the results.
References: