Hi guys,

I just now had a need for a query that involved checking a value
property in a list, which the Query API does not support. To get
around that I did it as a named query instead, but found that the RDF
query did not have support for variables in named queries. So, I
implemented that. My usecase is: "find a user with a given email
address". Here's how to do it:

First import the finder in the module where you want to declare the
named query. I did it in my application layer, like so:
      NamedQueries namedQueries = new NamedQueries();
      namedQueries.addQuery(      new NamedSparqlDescriptor("finduserwithemail",
                      "PREFIX ns0:
<urn:qi4j:type:org.qi4j.api.entity.Identity#>\n" +
                              "        PREFIX rdf:
<http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n" +
                              "        PREFIX rdfs:
<http://www.w3.org/2000/01/rdf-schema#>\n" +
                              "        SELECT DISTINCT ?identity\n" +
                              "        WHERE {\n" +
                              "        ?entity rdf:type
<urn:qi4j:type:se.streamsource.streamflow.web.domain.entity.user.UserEntity>.\n"
+
                              "        ?entity ns0:identity ?identity.\n" +
                              "        ?entity
<urn:qi4j:type:se.streamsource.streamflow.domain.contact.Contactable-Data#contact>
?v0.\n" +
                              "        ?v0
<urn:qi4j:type:se.streamsource.streamflow.domain.contact.ContactValue#emailAddresses>
?email\n" +
                              "        }"));
      module.importServices(NamedEntityFinder.class).
              importedBy(ImportedServiceDeclaration.SERVICE_SELECTOR).
              setMetaInfo(namedQueries).
              setMetaInfo(ServiceQualifier.withId("RdfIndexingEngineService"));
---
This imports the standard RDF query service, which allows me to add
the query as metainfo in my own layer, rather than where the
RdfIndexingEngineService is defined (infrastructure layer).

The query, as you can see, has a number of "?" variables, each of
which become potential variables for the query. Only ?email is an
actual variable I want to set though, as the others will be inferred
by Sesame.

To use, I did this:
Query<Drafts> finduserwithemail = qbf.newNamedQuery(Drafts.class,
uowf.currentUnitOfWork(), "finduserwithemail");
finduserwithemail.setVariable("email",
"[{\"contactType\":\"HOME\",\"emailAddress\":\"" + email.from().get()
+ "\"}]");
Drafts user = finduserwithemail.find();
---
So, lookup the named query given the name, and then set the "email"
variable to what I want to match. Since it's a JSON-ized value I want
to match it's a bit messy, but it does the job.

This will allow you to make any type of queries in RDF, without having
to define them where the actual service is defined, and then easily
access and use them in code.

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to