Jena - Find statements by property and object class - jena

I'm looking for the way how to get all statements from my model by its property and by a class of an object.
For example I have property :driverOf and individuals either of type Bus or Truck. Then I want to get all statements where the property is :driverOf and the object is instanceOf Bus. Thanks.
UPDATE 1
Actually I need the result to be a set of statements (resp. StmtIterator) because in my app I use statement objects already. I think the most clean solution would be to have subproperties of :driverOf property, something like :driverOfBus and :driverOfTruck. But it would make my app more complicated, so I would like to find out some simple workaround.

You could use sparql query. You have to replace labels with full namespaces.
String queryString =
"SELECT ?x WHERE { ?x driverOflabel ?y . {?y a Buslabel} UNION { ?y a Trucklabel} . }";
Query query = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(query, YOURMODEL);
try {
ResultSet results = qexec.execSelect();
while(results.hasNext()) {
QuerySolution soln = results.nextSolution();
System.out.println(soln.toString());
}
} finally {
qexec.close();
}

I hope i understood this correctly:
Say you have model m and namespace NAMESPACE
// Get the property and the subject
Property driverOf = m.getProperty(NAMESPACE + "driverOf");
Resource bus = m.getResource(NAMESPACE + "bus");
// Get all statements/triples of the form (****, driverOf, bus)
StmtIterator stmtIterator = m.listStatements(null, driverOf, bus);
while (stmtIterator.hasNext()){
Statement s = stmtIterator.nextStatement();
Resource busDriver = s.getObject();
// do something to the busdriver (only nice things, everybody likes busdrivers)
}

Related

this method cannot be translated into a store expression [duplicate]

I saw this code work with LINQ to SQL but when I use Entity Framework, it throws this error:
LINQ to Entities does not recognize the method 'System.Linq.IQueryable'1[MyProject.Models.CommunityFeatures] GetCommunityFeatures()' method, and this method cannot be translated into a store expression.`
The repository code is this:
public IQueryable<Models.Estate> GetEstates()
{
return from e in entity.Estates
let AllCommFeat = GetCommunityFeatures()
let AllHomeFeat = GetHomeFeatures()
select new Models.Estate
{
EstateId = e.EstateId,
AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
};
}
public IQueryable<Models.CommunityFeatures> GetCommunityFeatures()
{
return from f in entity.CommunityFeatures
select new CommunityFeatures
{
Name = f.CommunityFeature1,
CommunityFeatureId = f.CommunityFeatureId
};
}
public IQueryable<Models.HomeFeatures> GetHomeFeatures()
{
return from f in entity.HomeFeatures
select new HomeFeatures()
{
Name = f.HomeFeature1,
HomeFeatureId = f.HomeFeatureId
};
}
LazyList is a List that extends the power of IQueryable.
Could someone explain why this error occurs?
Reason:
By design, LINQ to Entities requires the whole LINQ query expression to be translated to a server query. Only a few uncorrelated subexpressions (expressions in the query that do not depend on the results from the server) are evaluated on the client before the query is translated. Arbitrary method invocations that do not have a known translation, like GetHomeFeatures() in this case, are not supported.
To be more specific, LINQ to Entities only support Parameterless constructors and Initializers.
Solution:
Therefore, to get over this exception you need to merge your sub query into the main one for GetCommunityFeatures() and GetHomeFeatures() instead of directly invoking methods from within the LINQ query. Also, there is an issue on the lines that you were trying to instantiate a new instance of LazyList using its parameterized constructors, just as you might have been doing in LINQ to SQL. For that the solution would be to switch to client evaluation of LINQ queries (LINQ to Objects). This will require you to invoke the AsEnumerable method for your LINQ to Entities queries prior to calling the LazyList constructor.
Something like this should work:
public IQueryable<Models.Estate> GetEstates()
{
return from e in entity.Estates.AsEnumerable()
let AllCommFeat = from f in entity.CommunityFeatures
select new CommunityFeatures {
Name = f.CommunityFeature1,
CommunityFeatureId = f.CommunityFeatureId
},
let AllHomeFeat = from f in entity.HomeFeatures
select new HomeFeatures() {
Name = f.HomeFeature1,
HomeFeatureId = f.HomeFeatureId
},
select new Models.Estate {
EstateId = e.EstateId,
AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
};
}
More Info: Please take a look at LINQ to Entities, what is not supported? for more info.
Also check out LINQ to Entities, Workarounds on what is not supported for a detailed discussion on the possible solutions.
(Both links are the cached versions because the original website is down)

Querying Relationships in Laravel 5.2

I am having issues trying to query an Eloquent relationship.
I have 2 tables
tbl_deals
id
deal_id
merchant_id
tbl_merchants
id
merchant_id
merchant_url_text
I defined a deal model as
class deal extends Model
{
public function merchant() {
return $this->hasOne('App\merchant', 'merchant_id', 'merchant_id');
}
}
Now, I want to query all deals based where merchant_url_text = a variable in my controller
Here's what I am trying
$deals = deal::with('merchant')->get(); //Retrieving all the deals with merchants
If I return $deals its giving me all deals with merchant relationship.
How do I constraint the deals by saying where merchant_url_text = $variable
I am trying
return $deals->where('merchant_url_text', $merchant_url_text)->get();
but it is giving me an error saying :
"Missing argument 1 for Illuminate\Support\Collection::get(), called in ..."
I tried to lookup the documentation for querying relationships in Laravel Docs. It talks about this example
$user = App\User::find(1);
$user->posts()->where('active', 1)->get();
In this case, its trying to get the first user and finding corresponding posts related to the user.
In my case I want to filter from all deals, the deals that have merchant_url_text = a specific variable in my controller.
Any help on how I can achieve this?
Thanks
Try the following code :
$specific_merchant_url_text = "i don't know";
$deals_with_specific_merchant_url_text = [];
$deals = deal::with('merchant')->get();
foreach($deals as $deal)
if( $deal->merchant->merchant_url_text==$specific_merchant_url_text)
array_push($deals_with_specific_merchant_url_text, $deal);
So you get array of deals with specific merchant url text in deals_with_specific_merchant_url_text.
Another approach using DB object :
$deals = DB::table('deals')
->join('merchants', 'deals.merchant_id', '=', 'merchants.id')
->select('deals.*')
->where('merchants.merchant_url_text', $merchant_url_text)
->get();
Yours with raw :
$deals = deal::selectRaw('tbl_deals.*')
->Join('merchants','deals.merchant_id','=','merchants.merchant_id')
->where('merchants.merchant_url_text', '=', $merchant_url_text) ->get();
Hope this helps.
With takes a callback. This will bring back all deals but only eager load merchants that match.
$deals = Deal::with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
Flip-side: if you only want deals with a matching merchant, use where has.
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->get();
If you want both, chain them:
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
I capitalized deal because it's standard. It wasn't capitalized in your example.
You can use query builder join query .
DB::table('tbl_merchants')
->join('tbl_deals', 'tbl_merchants.merchant_id', '=','tbl_deals.merchant_id')
->where('tbl_merchants.merchant_url_text',$merchant_url_text)
->get();

Grails search owned objects by properties

I am trying to find the proper syntax for a query that I know has got to be very common but couldn't find a code example for.
class ObjA {
...
static hasMany = [b:ObjB]
}
if a is an instance of ObjA, I want to perform a query like:
a.b.findAllBsSuchThat(b.someproperty = somevalue)
In order to avoid (N+1) queries for lazy associations per a, you can use a criteria as:
ObjA.withCriteria {
b {
eq 'someProperty', someValue
}
}
or where queries:
ObjA.where { b.someProperty == somevalue }.list()
If you use something like a.b.findAllBsSuchThat(b.someproperty = somevalue) then you would be getting all b's for a and then filtering on the result. This will affect the performance and will unnecessary.

gorm projection and loss of metainformation

When using projection on the properties, the result is returned as the list with the elements in the same sequence as that defined in the projections block. At the same time the property names are missing from the list and that is really disadvantageous to the developer as the result would be passed along and the caller needs to know what value belongs to which property. Is there a way to return a map from the Criteria query with property name as the key to the value?
so, the following code:
def c = Trade.createCriteria()
def remicTrades = c.list {
projections {
property('title', 'title')
property('author.name', 'author')
}
def now = new Date()
between('publishedDate', now-365, now)
}
This returns:
[['book1', 'author1']['book2', 'author2']]
Instead I would like it to return:
[[book:'book1', author:'author1'][book:'book2', author:'author2']]
I know I can arrange this way after getting the result but I earnestly feel that the property alias should have been used by the criteria to return a list of map that mimics the result of the SQL query and not a bland list.
Duplicate: Grails queries with criteria: how to get back a map with column?
And the corresponding answer (and solution): https://stackoverflow.com/a/16409512/1263227
Use resultTransformer.
import org.hibernate.criterion.CriteriaSpecification
Trade.withCriteria {
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
projections {
property('title', 'title')
property('author.name', 'author')
}
def now = new Date()
between('publishedDate', now-365, now)
}
Agree with your question reasoning, this really should be part of the core GORM solution. That said, here's my workaround;
def props = ['name','phone']
def query = Person.where {}.projections {
props.each{
property(it)
}
}
def people = query.list().collect{ row->
def cols = [:]
row.eachWithIndex{colVal, ind->
cols[props[ind]] = colVal
}
cols
}
println people // shows [['name':'John','phone':'5551212'],['name':'Magdalena','phone':'5552423']]

Querying values from a Map Property in a Grails Domain Class

I found the solution Burt Beckwith offered in this question: add user define properties to a domain class and think this could be a viable option for us in some situations. In testing this, I have a domain with a Map property as described in the referenced question. Here is a simplified version (I have more non-map properties, but they are not relevant to this question):
class Space {
String spaceDescription
String spaceType
Map dynForm
String toString() {
return (!spaceType)?id:spaceType + " (" + spaceDescription + ")"
}
}
I have some instances of space saved with some arbitrary data in the dynForm Map like 'Test1':'abc' and 'Test2':'xyz'.
I am trying to query this data and have succesfully used HQL to filter doing the following:
String className = "Space"
Class clazz = grailsApplication.domainClasses.find { it.clazz.simpleName == className }.clazz
def res = clazz.executeQuery("select distinct space.id, space.spaceDescription from Space as space where space.dynForm['Test1'] = 'abc' " )
log.debug "" + res
I want to know if there is a way to select an individual item from the Map dynForm in a select statement. Somehting like this:
def res = clazz.executeQuery("select distinct space.id, elements(space.dynForm['Test1']) from Space as space where space.dynForm['Test1'] = 'abc' " )
I can select the entire map like this:
def res = clazz.executeQuery("select distinct elements(space.dynForm) from Space as space where space.dynForm['Test1'] = 'abc' " )
But I just want to get a specific instance based on the string idx.
how about to use Criteria, but i don't have any sql server so i haven't tested yet.
def results = Space.createCriteria().list {
dynForm{
like('Test1', 'abc')
}
}

Resources