Sparql Query Optimization for possible predicates between entity types - query-optimization

I am trying to formulate a sparql query such that I get all the possible predicates between two entity types. Here is my approach:
SELECT distinct ?p
WHERE
{ ?url1 rdf:type <http://dbpedia.org/ontology/Town> .
?url2 rdf:type <http://dbpedia.org/ontology/District> .
?url1 ?p ?url2 .}
However, this approach is not efficient, is there any way to optimize this query?

Related

Check membership of a certain class of an individual in Protege

I understand that we can list the members of a certain class in Protege. All I need to do is to start the reasoner, visit the DL Query tab, put the name of the class in the Query box, keep Instances checked and the press Execute. I get a list of all the individuals who belong to this class.
I wanted to issue a DL query to check whether individual a belongs to class A.
Is there a way I can do this in Protege? If this is not possible in Protege, is there an alternative?
You could write something like this: {a} and A.
If a belongs to A, then it will be displayed in the "Instances" section:
One would have to be able to use Snap SPARQL Query Plugin for this purpose.
Snap SPARQL Query Plugin, as opposed to SPARQL Query Plugin, is able to work with inferred knowledge.
Unfortunately, Snap SPARQL Query Plugin does not support ASK queries. Try the following:
SELECT DISTINCT ?is WHERE { :a rdf:type :A . BIND (("Found!") AS ?is) }

Is it possible to pass the datalog wildcard `_` into a parameterized query?

Is it possible to pass a wildcard _ into a parameterized query? Something like this:
(d/q [:find ?e
:in $ ?type
:where [?e :type ?type]] db _)
When I tried this as written above it threw an error. Is there a way to do this?
I know that I can get everything with a query that looks like this:
(d/q [:find ?e
:where [?e :type]] db)
But my goal is to avoid needing to build separate queries when I don't want to filter results by :type. The use case is, e.g., and API endpoint that may or may not filter results.
If I understand you correctly, you should be able to type:
(d/q [:find ?e
:in $
:where [?e :type]] db )
In Datomic, any unspecified values are considered to be wildcards. The above query will return a list of all entities that have the :type attribute, regardless of value.
Update
Datomic's query is designed to accept a plain value like 5 or :awesome to be substituted into the ?type variable. A symbol like _ (or the quoted version '_) does not fit the pattern expected by Datomic.
Just for fun, I tried several variations and could not get it Datomic to accept the symbol '_ for the ?type variable in the way you proposed. I think you'll have to write a separate query for the wildcard case.
Essentially, the wildcard _ is a special symbol (aka "reserved word") in the Datomic query syntax just like $. Datomic also enforces that query variables begin with a ? like ?e or ?type. These requirements are a part of the Datomic DSL that you can't change.
The only workaround besides hand-writing separate queries would be to dynamically compose the query vector from a base-part and add-on parts. Whether that is easier or harder than hand-writing the different queries depends on your specific situation.

it is possible to use parentheses in solr

I'm newbie to solr and I wonder if it is possible to use parentheses like this:
if I want to search for field1:val1 NOT field2:val2 NOT field3:val3, can I do : field1:val1 NOT (field2:val2 AND field3:val3).
I see that in the doc there is something similar but it doesn't exactly what I need
Yes, lucene queries do allow the use of parentheses in queries, and the syntax you've provided is perfectly valid.
However, No, those two queries will not get the same results. This isn't some Lucene quirk, though, those two queries are not logically equivalent. According to De Morgan's Laws: NOT a AND NOT b = NOT (a OR b)
field1:val1 NOT field2:val2 NOT field3:val3 is equivalent to field1:val1 NOT (field2:val2 OR field3:val3). These would return results containing "val1", but neither of "val2" or "val3"
field1:val1 NOT (field2:val2 AND field3:val3) would return results that have "val1", and not both of "val2" and "val3". Results could have either of them present, just not both.
you can use - to achieve that.
e.g
/select?q=field1:val1&fq=-field2:val2&fq=-field3:val3
you can add as many filter queries(fq) as you want .
So basically q will return all the docs that have field with value val1 and then the filter query(fq) will filter out the results so that the only docs that will return are which do not have field2 with value val2 and field3 with value val3

SPARQL date filter query for RDF

I am querying using SPARQL, which works fine. But when I add a data filter it doesn't throw an error but also it doesn't do the filter. The final part is that I should be able to query between two dates:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX hotel: <http://users.jyu.fi/~mimomuki/everything/hotel#>
SELECT *
WHERE { ?room hotel:hasCity ?sender; hotel:hasFirstDay ?Firstday
FILTER ( ?Firstday >= "2016-09-01"^^xsd:date )
}
If you want to compare dates, you may want to ensure proper data type of operands in your filter expression. You can to that by casting both values to xsd:dateTime
FILTER ( xsd:dateTime(?Firstday) >= xsd:dateTime("2016-09-01") )
SPARQL FILTER works as a positive filter. If the expression is true for any match, then the match stands. Otherwise the match is discarded and there won't be any bindings for ?room ?sender and ?Firstday. No error will be thrown as the query correctly returns no matches.
This Filter worked for me:
FILTER (?FirstDay>= "2016-09-01T00:00:00Z"^^xsd:dateTime)

Find entity with most occurrences in a relation in Datomic

Is there a way to express this kind of logic purely inside a query?
(def e-top
(let [res (d/q '[:find ?e (count ?p)
:where [?p :likes ?e]] db)]
(first (apply max-key last res))))
If you need to work within one query, then aggregate of aggregates problems are best tackled with subquery (a nested call to query inside query). See this answer on the Datomic mailing list which includes a similar (not identical) query on the results of an aggregate against mbrainz:
(d/q '[:find ?track ?count
:where [(datomic.api/q '[:find ?track (count ?artist)
:where [?track :track/artists ?artist]] $) [[?track ?count]]]
[(> ?count 1)]]
(d/db conn))
For your case (assuming work stays in Clojure), apply will be faster and simpler. Subqueries that only need to do something simple (e.g. get something associated with the max value) tend to make more sense if you're using the REST API or some other client wrapping around Datomic where you don't have the perf benefits associated with the Peer library being in process.

Resources