I'm new to SPARQL, and I am trying to select a property based on the content of the subject. For example, using the RDF data below, I want to return the result containing "var2_1":
<rdf:Description rdf:about="http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var0">
<rdf:type rdf:resource="http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var2_0"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var1">
<rdf:type rdf:resource="http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var2_1"/>
</rdf:Description>
This is the query I am writing, but it returns nothing, and I can't seem to find a way to specify that the subject should contain "var1":
SELECT ?t
WHERE {
?s rdf:type ?t
FILTER regex(?s, "var1")
}
I would appreciate help on the right way to do this.
The subject is not a string literal value, but an IRI: http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var1. To match this, you should not be using a regular expression, but instead use the actual IRI itself:
SELECT ?t
WHERE {
?s rdf:type ?t
FILTER(?s = <http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var1>)
}
or more succinct:
SELECT ?t
WHERE {
<http://www.ontologydesignpatterns.org/ont/fred/domain.owl#var1> rdf:type ?t
}
The other answer has already pointed out that your ?s is a URI, and should be matched directly instead of using a regular expression. In addition, it is worth keeping in mind that matching specific URIs becomes much simpler if you have the right prefixes defined. If we define a prefix for the file's URI, then the actual query pattern becomes much simpler:
PREFIX fred: <http://www.ontologydesignpatterns.org/ont/fred/domain.owl#>
SELECT ?t
WHERE {
fred:var1 rdf:type ?t
}
The query can become even simpler: rdf:type has a built-in abbreviation “a”, and the WHERE keyword is optional:
PREFIX fred: <http://www.ontologydesignpatterns.org/ont/fred/domain.owl#>
SELECT ?t {
fred:var1 a ?t
}
Finally, if you really want to use a regular expression to match the URI, you can do that by converting the URI to a string using str:
SELECT ?t {
?s a ?t
FILTER regex(str(?s), "var1")
}
But compared to the other options, this will be extremely slow on larger datasets.
Finally finally, to support AKSW's comment, here is the file converted from RDF/XML to Turtle:
PREFIX fred: <http://www.ontologydesignpatterns.org/ont/fred/domain.owl#>
fred:var0 a fred:var2_0.
fred:var1 a fred:var2_1.
Related
Given a tree-sitter tree for some HTML elements:
<script>console.log('should parse as js')</script>
<script async defer>console.log('works')</script>
(script_element
(start_tag
(tag_name))
(raw_text
; ... etc
)
(end_tag
(tag_name)))
(script_element
(start_tag
(tag_name)))
(attribute
(attribute_name))
(attribute
(attribute_name))
(raw_text
; ... etc
)
(end_tag
(tag_name)))
Broken Query
This query fails when used in neovim's tree-sitter html grammar injections.scm, returning an invalid field error
(script_element
(start_tag !attribute))
How would I query for <script> elements which do not have any attributes? Is it necessary for the grammar to assign a field name to the child in order for queries to negate it?
This was answered on GitHub discussions: https://github.com/nvim-treesitter/nvim-treesitter/discussions/2582
The gist of this answer is that you query for a script_element for which the tag name is the last child, so there are thus no other children such as attributes:
(script_element (start_tag (tag_name) .)) #foo
I can't perform a wildcard-query on an embedded-list property of vertex (or edge).
For example:
Assume we have a Person class with a multi-value property named Nicknames and one instance of it:
{
"#type": "d",
"#rid": "#317:0",
"#version": 1,
"#class": "Person",
"Nicknames": [
"zito",
"ziton",
"zitoni"
]
}
then,
Select FROM Person WHERE Nicknames like "zit%"
returns empty result-set, while:
Select FROM Person WHERE Nicknames ="zito" returns 1 item correctly.
There's a NOTUNIQUE_HASH_INDEX index on the field Nicknames.
I've tried many ways (contains, index-query...) with no luck :(
I'm probably missing something basic.
I know is not an ideal solution what i'm going to write but, to stay stuck with your requirement of "query by wildcard" this is the only way that worked for me, as AVK stated is a better idea work with a Lucene index, but with the standard implementation i was unable to let it work, now here what i've done:
Use studio to create a javascript function with 2 parameter with name "array" and "rule", lets name the function "wildcardSearch"
past this code in the body of the function (is just simple javascript change it if it dosent do the job) :
for(i=0; i<array.length ; i++){
rule= rule.split("*").join(".*");
rule= rule.split("*").join(".*");
rule= "^" + ruleValue + "$";
var regex = new RegExp(rule);
if (regex.test(array[i]))
return true;
}
return false;
Remember to save the fucntion
now you can query:
Select from Person where wildcardSearch(nicknames,'zit*')=true
CONSIDERATIONS: is a brute force method, but show how "funny" can be play around with the "stored procedure" in OrientDb so i've decided to share it anyway, if performance are your main goal this things is not for you, it scan all the class and do the loop on the array to apply the regex. An Index is a way better solution, or change your db with a different data structure.
You can try this:
select from Person where Nicknames containstext 'zit'
Hope that helps
I have a requirement to fetch search results based on partial text match. For example, if there is a node under products say "apple-iphone-6" and the user enters "iphone" text in the searchbox, I should still be able to fetch the result.
I tried the below query on querybuilder and it worked:
http://localhost:4502/bin/querybuilder.json?path=/etc/commerce/products&type=nt:unstructured&nodename=*iphone*
But, how to implement this programatically for the *iphone* part? I am creating a query using the predicates as follows
String searchTerm = "iphone";
map.put("path", "/etc/commerce/products");
map.put("type", "nt:unstructured");
map.put("nodename", searchTerm);
Query query = queryBuilder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
But I do not get any results, reason being, the node name(apple-iphone-6) does not exactly match the search term (iphone).
But the same thing works fine in case I append * to the nodename value which then implements partial text based search in the querybuilder example. What change should I do in the code to get results based on partial node name matches?
You already have found the solution on your own, the NodenamePredicateEvaluator accepts wildcard arguments, so you would need to surround the search term with wildcards, for example like this:
String searchTerm = "iphone";
...
map.put("nodename", "*" + searchTerm + "*");
in this case "like" opration can be used:
EX-> patial text serach for jcr:title
map.put("group.1_property", "fn:lower-case(#jcr:content/jcr:title)");
map.put("group.1_property.value", "%"+fulltextSearchTerm + "%");
map.put("group.1_property.operation", "like");
For just the nodename the answer posted is correct, but if you want to search inside properties as well then :
map.put("fulltext","*"+searchTetm +"*");
map.put("fulltext.relPath","jcr:content");
Can we have a condition clause in APEX form :
Value of Item / Column in Expression 1 = Expression 2,
where expression1 is a form variable like P19__ROW_last_update_ts and
the second expression2 is a sql query like select max(date_max) from table
Please help me on this.
You can do this by adding a property on your form controller that executes the query and returns the result. The property will look something like:
public String getExampleProperty {
get {
return [/*some query in here*/].someProperty;
}
}
And then in your form, you'll reference the value like:
{!exampleProperty}
Note that you don't use the 'get' prefix in your visual force markup.
Hope this helps!
I pass my template a TreeSet with Strings. However, when I loop over the set like this:
#(usernames : TreeSet[String])
#for( name <- usernames){
#name ,
}
However, the names are never printed in the correct order.
How can I iterate over my set in my template and print the names in order?
This has something to do with the way Scala Templates work. I suspect your TreeSet collection is under the hood mapped to a different collection and as a result the ordering is not preserved.
There is clearly a difference between the behavior of the Scala for loop and the for loop in Scala Templates. If you run your code as regular Scala code the order of the TreeSet is obviously preserved:
val users = TreeSet("foo", "bar", "zzz", "abc")
for (user <- users) {
println(user)
}
One of the ways to solve the problem is to use the iterator in the Scala Template:
#for(name <- usernames.iterator) {
#name ,
}
or transform the TreeSet to a sequence:
#for(name <- usernames.toSeq) {
#name ,
}
There is no guaranteed ordering for any Set class, so it's best to sort it before iterating.
If you mean to print them alphabetically, you should convert it into a List and then iterate
#(usernames : TreeSet[String])
#for( name <- usernames.toList().sortWith(_ < _)){
#name ,
}