As far as I understand some basic principles of the Semantic Web (especially the Resource Description Framework RDF), the semantic is described in tripels with subject, predicate and object.
So for example I can express
Pancake consistsOf Egg
Pancake consistsOf Flour
Pancake consistsOf Milk
Pancake producibleBy PancakeRecipe1
Pancake producibleBy PancakeRecipe2
Main question: How to describe process steps and time dependent statements with Semantic Web triples?
Process steps, amounts
How can I express amounts in a process step with tripels? For example the instruction "use 2 eggs". Maybe this is an approach: PancakeRecipe1 useEggs 2. But this would imply that when I want to offer a universal process description (not only for pancakes), I have to add a predicate for every thing that could ever be part of everything else (even those things that are unknown at the moment).
Another approach: PancakeRecipe1 use2 Egg. This would imply that I have to add a predicate for every amount (even floats). Not practical.
A third approach:
PancakeRecipe1 use 2Eggs
2Eggs isAmountOf Egg
2Eggs value 2
This way at least the number of predicates is constant this way.
A fourth approach: maybe misuse the possibility to upt a literal into the object and combine an amount and the reference to the object into the literal: PancakeRecipe1 use 2,Egg.
A fifth approach: can there be predicates at a predicate? For example PancakeRecipe1 use[amount 2] Egg?
Process steps, order
How can I express the order a pancake recipe with tripels? This would be an additional information at the predicate, I guess (if there may be any additional information at the predicate):
PancakeRecipe1 use[amount 2, order 1] Egg
PancakeRecipe1 use[amount 200, unit g, order 2] Flour
PancakeRecipe1 use[amount 200, unit ml, order 3] Flour
Process steps, conditions
What is the triple expression for "Use either butter or margarine"?
Time dependent statements
How can a Semantic Web triple express chronological events or states? For example the amount of sold pancakes in a city (or maybe the more practical use case: the amount of citizens in a city in history)? There could be something like this:
Berlin soldPancakes2018 12345678
Berlin soldPancakes2019 14567890
Berlin soldPancakes2020 20123456
Or maybe Berlin soldObjects[object Pancake, periodFrom 2018-01-01, periodTo 2018-12-31] 12345678?
How is this expressable in RDF?
There are many subquestions not really related to the main question to fully answer each one of them. You also didn't specify whether you are looking for a particular vocabulary, or just for idea about transforming real-world entities into semantic triples. Let's say we are creating an ontology for the moment.
Process steps, amounts
A recipe is similar to a programming function: it has some ingredients (arguments) and steps (statements) to produce the result. You may want to describe them separately.
<recipe> :uses [
:product :egg ;
:minAmount 2
] .
Process steps, order
The individual steps can work in a similar manner, just in a list:
<recipe> :steps (
[
:action :break ;
:object [
:product :egg ;
:amount 2
] ;
:result _:x
]
[
:action :add ;
:object _:x
]
[
:action :add ;
:object [
:product :flour ;
:amount "200"^^:g
]
]
[
:action :mix
]
) .
Process steps, conditions
We can link from ingredients or steps to alternatives:
[
:action :add ;
:object [
:product :flour ;
:amount "200"^^:g
]
:alternative [
:action :add ;
:object [
:product :magicFlour ;
:amount "10"^^:g
]
]
]
As you can see, it is not hard to conceive a method for transforming ideas to triples that are sensible. What's hard is to find a consistent way for transforming all such sensible ideas to triples. Luckily, we are already covered by existing ontologies.
I find the RDFa Core Initial Context a useful place to check for recommended and common vocabularies. From there we can pick what is useful:
For describing complex time points or intervals, there is the Time Ontology.
Offers with a high degree of details can be described by GoodRelations.
For statistics and measurements, there are Data Cubes.
And lastly, Schema.org covers many real-world entities, including recipes.
Related
my ontology about social network. And we have simple SWRL rules two people(?p1,?p2) workInOrg Org(?org) => colleagueOf(?p1,?p2) and if thier colleague, one people workInOrg => the other person also works in that Org. I also build OWL Axioms but it cant take affect on Graphdb. Another try is that i wrote a custom rule, but Graphdb only allow to choose one Rule (In my case "owrl2-rl") and my custom rule only take affect when combining on this rule OWL2-RL. Is there a way to use combine rules and write rule effienctly?
SHACL validation is good. Does graphdb has OWL constraint validation ??? (ex: domain-range validation ?)
Thanks.
Damyan's comment above provides the answer
One can do this also with OWL2 RL and property chains (see https://www.w3.org/TR/owl2-profiles/#OWL_2_RL in https://www.w3.org/TR/owl2-profiles/#OWL_2_RL). This would not require custom rules, but inference will be a bit slower
This is how it can work:
:worksIn owl:inverseOf :employerOf
:colleagueOf owl:propertyChainAxiom ( :worksIn :employerOf ) .
:worksIn owl:propertyChainAxiom ( :colleagueOf :worksIn ) .
This question is language independent. Let's not worry about frameworks or implementation, let's just say everything can be implemented and let's look at REST API in an abstract way. In other words: I'm building a framework right now and I didn't see any solution to this problem anywhere.
Question
How one can construct REST URL endpoint for intersection of two independent REST paths which return collections? Short example: How to intersect /users/1/comments and /companies/6/comments?
Constraint
All endpoints should return single data model entity or collection of entities.
Imho this is a very reasonable constraint and all examples of Hypermedia APIs look like this, even in draft-kelly-json-hal-07.
If you think this is an invalid constraint or you know a better way please let me know.
Example
So let's say we have an application which has three data types: products, categories and companies. Each company can add some products to their profile page. While adding the product they must attach a category to the product. For example we can access this kind of data like this:
GET /categories will return collection of all categories
GET /categories/9 will return category of id 9
GET /categories/9/products will return all products inside category of id 9
GET /companies/7/products will return all products added to profile page of company of id 7
I've omitted _links hypermedia part on purpose because it is straightforward, for example / gives _links to /categories and /companies etc. We just need to remember that by using hypermedia we are traversing relations graph.
How to write URL that will return: all products that are from company(7) and are of category(9)? In otherwords how to intersect /categories/9/products and /companies/7/products?
Assuming that all endpoints should represent data model resource or collection of them I believe this is a fundamental problem of REST Hypermedia API, because in traversing hypermedia api we are traversing relational graph going down one path so it is impossible to describe such intersection because it is a cross-section of two independent graph paths.
In other words I think we cannot represent two independent paths with only one path. Normally we traverse one path like A->B->C, but if we have X->Y and Z->Y and we want all Ys that come from X and Z then we have a problem.
So far my proposition is to use query strings: /categories/9/products?intersect=/companies/9 but can we do better?
Why do I want this?
Because I'm building a framework which will auto-generate REST Hypermedia API based on SQL database relations. You could think of it as a trans compiler of URLs to SELECT ... JOIN ... WHERE queries, but the client of the API only sees Hypermedia and the client would like to have a nice way of doing intersections, like in the example.
I don't think you should always look at REST as database representation, this case looks more of a kind of specific functionality to me. I think I'd go with something like this:
/intersection/comments?company=9&product=5
I've been digging after I wrote it and this is what I've found (http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api):
Sometimes you really have no way to map the action to a sensible RESTful structure. For example, a multi-resource search doesn't really make sense to be applied to a specific resource's endpoint. In this case, /search would make the most sense even though it isn't a resource. This is OK - just do what's right from the perspective of the API consumer and make sure it's documented clearly to avoid confusion.
What You want to do is to filter products in one of the categories ... so following Your example if we have:
GET /categories/9/products
Above will return all products in category 9, so to filter out products for company 7 I would use something like this
GET /categories/9/products?company=7
You should treat URI as link to fetch all data (just like simple select query in SQL) and query parameters as where, limit, desc etc.
Using this approach You can build complex and readable queries fe.
GET /categories/9/products?company=7&order=name,asc&offset=10&limit=20
All endpoints should return single data model entity or collection of
entities.
This is NOT a REST constraint. If you want to read about REST constraints, then read the Fielding dissertation.
Because I'm building a framework which will auto-generate REST
Hypermedia API based on SQL database relations.
This is a wrong approach and has nothing to do with REST.
By REST you describe possible resource state transitions (or operation call templates) by sending hyperlinks in the response. These hyperlinks consist of a HTTP methods and URIs (and other data which is not relevant now) if you build the uniform interface using the HTTP and URI standards, and we usually do so. The URIs are not (necessarily) database entity and collection identifiers and if you apply such a constraint you will end up with a CRUD API, not with a REST API.
If you cannot describe an operation with the combination of HTTP methods and already existing resources, then you need a new resource.
In your case you want to aggregate the GET /users/1/comments and GET /companies/6/comments responses, so you need to define a link with GET and a third resource:
GET /comments/?users=1&companies=6
GET /intersection/users:1/companies:6/comments
GET /intersection/users/1/companies/6/comments
etc...
RESTful architecture is about returning resources that contain hypermedia controls that offer state transitions. What i see here is a multistep process of state transitions. Let's assume you have a root resource and somehow navigate over to /categories/9/products using the available hypermedia controls. I'd bet the results would look something like this in hal:
{
_links : {
self : { href : "/categories/9/products"}
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
If you want your client to be able to intersect this with another collection you need to provide to them the mechanism to perform this. You have to give them a hypermedia control. HAL only has links, templated links, and embedded as control types. let's go with links..change the response to:
{
_links : {
self : { href : "/categories/9/products"},
x:intersect-with : [
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 1",
title : "Company 6 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 2",
title : "Company 5 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 3",
title : "Company 7 products"
}
]
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
Now the client just picks the right hypermedia control (aka link) based on the title field of the link.
That's the simplest solution. But you'll probably say there's 1000's of companies i don't want 1000's of links...well ok if that;s REALLY the case...you just offer a state transition in the middle of the two we have:
{
_links : {
self : { href : "/categories/9/products"},
x:intersect-options : { href : "URL to a Paged collection of all intersect options"},
x:intersect-with : [
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 1",
title : "Company 6 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 2",
title : "Company 5 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 3",
title : "Company 7 products"
}
]
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
See what i did there? an extra control for an extra state transition. JUST LIKE YOU WOULD DO IF YOU HAD A WEBPAGE. You'd probably put it in a pop up, well that's what the client of your app can do too with the result of that control.
It's really that simple...just think how you'd do it in HTML and do the same.
The big benefit here is that the client NEVER EVER needed to know a company or category id or ever plug that in to some template. The id's are implementation details, the client never knows they exist, they just executed Hypermedia controls..and that is RESTful.
I'm trying to figure out how to make some queries through which I should get fashion related content, like an list of known cloth types, or cloth manufactures, or well known fashion designers.
I have spent the last few days trying to figure out to make such an query through DBpedia or Freebase, but I couldn't seem to figure it out. Examples that kinda match what I need I couldn't find...
Can someone help me with this, some short example on which I can start to work on or some tutorials that explain how can I achieve something like this?
Thank you
Later Edit
I have also found that DBpedia contains an ontology property "dressCode" and I've found these pages: http://en.wikipedia.org/wiki/Dress_code_(Western) and http://en.wikipedia.org/wiki/Dress_code which lists some basic dress codes, like "Formal", "Casual"...
Now my idea is to get properties from each one of these sub-categories (or what they are defined as on DBpedia, as I see they differ from one other).
Any suggestion on how to do this ?
Later Edit
I have managed to make some queries to display some information that could actually help me:
SPARQL - list of social events
SELECT DISTINCT (?label as ?sub)
WHERE {
{
?sub skos:broader <http://dbpedia.org/resource/Category:Social_events> .
?sub rdfs:label ?label.
OPTIONAL {?subsub dcterms:subject ?sub}
}
}
SPARQL - list of dress codes
SELECT DISTINCT (?label as ?dressCode)
WHERE {
{
?dressCode dcterms:subject <http://dbpedia.org/resource/Category:Dress_codes> .
?dressCode rdfs:label ?label.
filter(langMatches(lang(?label),"EN"))
}
}
Now I would like to retrieve the "subject of" for each dress code so that I can connect somehow the dress codes to the social events, but I'm having issues to do that.
Later Edit
I got to the conclusion that I can't find an ontology that actually matches my needs. Basically I need to get cloth properties based on event types so I can make cloth recommendations. Except the restrictions from the event types I also want to add other properties like the current fashion trend, the season in which the event will take place, geo-location (if possible), and other small details like these.
Now I'm trying to use existing ontologies and data that exists on DBpedia & Freebase, like: 'Dress code', 'Event type', 'Colors', 'Fashion designer', 'Fabric', 'Texture', 'Manufacturer', 'Size' and combine them into an ontology which I can actually use in my project to actually make cloth recommendations.
Can anyone help me with some guidelines on how I can do this ? I tried to use Protege to combine some ontologies and extend them after that, but finally I failed to do this.
May be one of the first places you can start with is the DBpedia ontology. When I search for keywords like Fashion, I can see that there are classes like FashionDesigner. So I can check about about the information about fashion designers in DPpedia with a simple SPARQL query like the following using the DPpedia public SPARQL endpoint.
(a) a list of fashion designers:
select distinct ?fashionDesigner
where {
?fashionDesigner a dbpedia-owl:FashionDesigner
}
LIMIT 100
(b) what are the information generally available about a fashion designer
select distinct ?property
where {
?fashionDesigner a dbpedia-owl:FashionDesigner;
?property ?value .
}
I can also select one of the results of query (a) such as Donna Karan take a look what kind of information she has.
So now, my task is to see who the well-known fashion designers. I don't know much about fashion but I see some of them have awards. So I can query for the fashion designers who have won awards.
(c) Fashion designers who have won awards
select distinct ?fashionDesigner ?award
where {
?fashionDesigner a dbpedia-owl:FashionDesigner;
dbpprop:awards ?award .
}
I was only using very basic SPARQL queries but you can use more complex queries when you get to know more about the fashion related concepts and properties in the data.
You can follow a similar approach for classes such as LineOfFashion, Clothing, etc.
For example
(d) a list of clothing manufactures
select distinct ?company where {
?company dbpedia-owl:product dbpedia:Clothing;
dcterms:subject category:Clothing_brands .
} LIMIT 100
The more you explore, you can build better queries. I hope this will help you to get started.
Here's a query that returns award winning fashion designers from Freebase: https://www.googleapis.com/freebase/v1/search?limit=10&scoring=entity&filter=(all+type%3A%2Faward%2Faward_winner+notable%3A%22fashion+designer%22)&lang=en&indent=true
There's a little on-line utility that you can use to experiment with this and check out some of the other items that you were interested in:
http://freebase-search.freebaseapps.com/?filter=(all+type%3A%2Faward%2Faward_winner+notable%3A%22fashion+designer%22)&limit=10&scoring=entity&lang=en
I am new in Freebase and I have a simple question . I would like to use Freebase KB to find relation between two entities. For example if I have name entities "Washington" and "United States" , I would like to send a query to Freebase and get :
Location/Location/Capital or Null in the case of No relation.
Thank you very much.
If you only want to go one ply out (ie nearest neighbors), this is pretty simple to do using the reflection API if you're using the online version of Freebase. If you're using the bulk downloads, you'll need to work with whatever query engine you're using (probably SPARQL unless you converted the RDF to something else).
If you want to find the shortest path(es) regardless of who far apart they are, it becomes a graph search algorithm.
EDIT: If you only want to find capitols, you can fill in your IDs in this query:
[{
"type": "/location/administrative_division_capital_relationship",
"capital": [{
"id": null
}],
"administrative_division": [{
"id": null
}],
"limit": 1
}]
Note that for Washington, D.C., this will return null because the data isn't in Freebase.
If you need to handle arbitrary properties, you'll need to use reflection. See https://developers.google.com/freebase/mql/ch03#reflection
Suppose I have the following models:
class Post < ActiveRecord::Base
has_many :authors
class Author < ActiveRecord::Base
belongs_to :post
And suppose the Author model has an attribute, name.
I want to search for all posts with a given author "alice", by that author's name. Say there is another author "bob" who co-authored a post with alice.
If I search for the first result using includes and where:
post = Post.includes(:authors).where("authors.name" => "alice").first
You'll see that the post only has one author now, even if in fact there are more:
post.authors #=> [#<Author id: 1, name: "alice", ...>]
post.reload
post.authors #=> [#<Author id: 1, name: "alice", ...>, #<Author id: 2, name: "bob", ...>]
The problem seems to be the combination of includes and where, which limits the scope correctly to the desired post, but at the same time hides all associations except for the one that is matched.
I want to end up with an ActiveRecord::Relation for chaining, so the reload solution above is not really satisfactory. Replacing includes by joins solves this, but does not eager load the associations:
Post.joins(:authors).where("authors.name" => "alice").first.authors
#=> [#<Author id: 1, name: "alice", ...>, #<Author id: 2, name: "bob", ...>]
Post.joins(:authors).where("authors.name" => "alice").first.authors.loaded?
#=> false
Any suggestions? Thanks in advance, I've been banging my head over this problem for a while.
I see what you're doing as expected behaviour, at least that's how SQL works... You're restricting the join on authors to where authors.id = 1, so why would it load any others? ActiveRecord just takes the rows that the database returned, it has no way of knowing if there are others, without doing another query based on the posts.id.
Here's one possible solution with a subquery, this will work as a chainable relation, and executes in one query:
relation = Post.find_by_id(id: Author.where(id:1).select(:post_id))
If you add the includes, you will see the queries happen one of two ways:
relation = relation.includes(:authors)
relation.first
# 1. Post Load SELECT DISTINCT `posts`.`id`...
# 2. SQL SELECT `posts`.`id` AS t0_r0, `posts`.`title` AS t0_r1, ...
relation.all.first
# 1. SQL SELECT `posts`.`id` AS t0_r0, `posts`.`title` AS t0_r1, ...
So depending on the scenario, ActiveRecord decides whether to look up the id with a simpler query before loading all the associated authors. Sometimes it makes more sense to run the query in 2 steps.
Coming back to this question after a long long time, I realized there is a better way to do this. The key is to do not one but two joins, one with includes and one with Arel using a table alias:
posts = Post.arel_table
authors = Author.arel_table.alias("matching_authors")
join = posts.join(authors, Arel::Nodes::InnerJoin).
on(authors[:post_id].eq(posts[:id])).join_sources
post = Post.includes(:authors).joins(join).
where(matching_authors: { name: "Alice" }).first
The SQL for this query is quite long since it has includes, but the key point is that it has not one but two joins, one (from includes) using a LEFT OUTER JOIN on the alias posts_authors, the other (from the Arel join) using an INNER JOIN on the alias matching_authors. The WHERE only applies to the latter alias, so results on the association in the returned results are not limited by this condition.
I ran into the same issue (which I describe as: where clause filters the associated model, rather than the primary model, when includes is used to prevent N+1 queries).
After flailing around trying various solutions, I found that using preload in conjunction with joins solves this for me. The Rails documentation is not super useful here. But apparently preload will explicitly use two separate queries, one to filter/select the primary model, and a second query to load the associated models. This blog post also has some insights that helped lead me to the solution.
Applying this to your models would be something like:
post = Post.preload(:authors).joins(:authors).where("authors.name" => "alice").first
I suspect that under the covers this is doing the same thing as your accepted answer, but at a nicer level of abstraction.
I wish the Rails docs were more explicit about how to do this. It's subtle enough that I wrote a bunch of tests around this precise situation in my code base.
Actually, it's because this code:
post = Post.includes(:authors).where("authors.name" => "alice").first
returns the first matched record because of the ".first". I think if you did this:
post = Post.includes(:authors).where("authors.name" => "alice")
you would get back all posts with "alice" and her other co-authors if I understand what you're asking correctly.