I'm just starting out learning SPARQL and I'm finding it a little difficult to navigate finding items and properties. Could anyone advise me on how to write a query which returns a person's grandfather? E.g. Tom Cruise's grandfather
Thanks!
May be you can try one of these:
select * where {
:personID :hasParent/:hasFather ?grandFather
}
select * where {
:personID :hasFather/:hasFather ?grandFather_fatherSide
}
select * where {
:personID :hasMother/:hasFather ?grandFather_motherSide
}
Legend:
:personID = a specific ID
:hasParent = relations a person with her father or mother
:hasFather = relations a person with her father
:hasMother = relations a person with her mother
Related
I have 2 nodes:
Students and Subjects.
I want to be able to add multiple student names to multiple subjects at the same time using cypher query.
So far I have done it by iterating through the list of names of students and subjects and executing the query for each. but is there a way to do the same in the query itself?
This is the query I use for adding 1 student to 1 subject:
MATCH
(s:Student)-[:STUDENT_BELONGS_TO]->(c:Classroom),
(u:Subjects)-[:SUBJECTS_TAUGHT_IN]->(c:Classroom)
WHERE
s.id = ${"$"}studentId
AND c.id = ${"$"}classroomId
AND u.name = ${"$"}subjectNames
AND NOT (s)-[:IN_SUBJECT]->(u)
CREATE (s)-[:IN_SUBJECT]->(u)
So I want to be able to receive multiple subjectNames and studentIds at once to create these connections. Any guidance for multi relationships in cypher ?
I think what you are looking for is UNWIND. If you have an array as parameter to your query:
studentList :
[
studentId: "sid1", classroomId: "cid1", subjectNames: ['s1','s2'] },
studentId: "sid2", classroomId: "cid2", subjectNames: ['s1','s3'] },
...
]
You can UNWIND that parameter in the beginning of your query:
UNWIND $studentList as student
MATCH
(s:Student)-[:STUDENT_BELONGS_TO]->(c:Classroom),
(u:Subjects)-[:SUBJECTS_TAUGHT_IN]->(c:Classroom)
WHERE
s.id = student.studentId
AND c.id = student.classroomId
AND u.name = in student.subjectNames
AND NOT (s)-[:IN_SUBJECT]->(u)
CREATE (s)-[:IN_SUBJECT]->(u)
You probably need to use UNWIND.
I haven't tested the code, but something like this might work:
MATCH
(s:Student)-[:STUDENT_BELONGS_TO]->(c:Classroom),
(u:Subjects)-[:SUBJECTS_TAUGHT_IN]->(c:Classroom)
WITH
s AS student, COLLECT(u) AS subjects
UNWIND subjects AS subject
CREATE (student)-[:IN_SUBJECT]->(subject)
How to make that query with eloquent
SELECT employees.first_name, companies.name FROM employees
JOIN companies ON employees.company_id = companies.id
My relationships
public function employees()
{
return $this->hasMany(Employee::class);
}
public function company()
{
return $this->belongsTo(Company::class);
}
I fetching the name with a given ID, but how can I find it for all. Or maybe I am thinking wrong
$employee = $employee->all()->find($id)->company->name;
I assumed your employees Model name as Employee and companies Model name as Company
$employees = Employee::with('company')->get();
if(!empty($employees)){
foreach($employees as $employee){
echo $employee->first_name;
echo $employee->company->name;
}
}
If you want to search per id then you may do as below.
$employee = Employee::with('company')->find($id);
echo $employee->company->name;
$employee = Employee::where('employees.id',$id)
->join('companies','companies.id','=','employees.company_id')
->select('employees.first_name', 'companies.name')
->first();
Firs Of all this is very bad practice:
$employee = $employee->all()->find($id)->company->name;
This returns all employee collection and then searches id in it. You can simply use Employee::find($id)
Now about your query, as I guess your company model has many employee and if you want to find all company employees you have to do like that:
$company->employees()->select('first_name')->get(); // Collection of Employee
If you want to get specific company employee with employee id you can do:
$company->employees()->select('first_name')->where('id', $id)->first(); // null or Employee
Lets say I have 3 collections:
Grandparents
{
_id:1,
name:old foo
}
Parents
{
_id:2,
grandparentId:1,
name: foo
}
Person
{
_id: 3,
parentId:2,
name: youngfoo
}
How do i optimize a query to find all person where person's grandparent's name = x?
Name is not unique in this case.
What i can think of so far:
1. Query all grandparents with name = x
2. Query all parents where grandparent ids == grandparent ids gotten from step 1
3. Query all persons where parent ids == parent ids gotten from step 2.
Doesn't feel very efficient. Can mongodb experts out there help me? Thanks!
I think you want to do something like this. I did not test this query, but this is what i would try in your place. This is only possible on 3.6 mongodb, because it supports multiple joins. The idea is to join all 3 collections. First join is Parents and Person by Parents id, and Persons "parentsId". Second join is Parents and Grandparents. Then you filter out by grandparent name and you will get a document that contains that grandparent, his son (parent), and his grandson(person). Then you just project the person.
db.Parents.aggregate([
{
$lookup:{
from:"Person",
localField:"_id",
foreignField:"parentId",
as:"Person"
}
},
{
$unwind:"$Person"
},
{
$lookup:{
from:"Grandparents",
localField:"grandparentId",
foreignField:"_id",
as:"Grandparents"
}
},
{
$unwind:"$Grandparents"
},
{$match:{Grandparents.name:"x"}},
{$project:{Person.name:1,Person._id:1}}
}])
I think this will do the trick
lets say i have this example as my app
http://sailsjs.org/#!/documentation/concepts/ORM/Associations/OnetoMany.html
For some big reasons(complicated) I cannot use Model.populate() and I'm stuck in using Model.query()
Does anyone know how to get the result as User.find().populate('pets') Using Model.query() Please
Thank you
You can do it like waterline adapters do to populate OneToMany:
Retrieve parents : select * from user ...
Retrieve children for each parent in only one query to not overload DBMS:
select * from pet where user = user1.id union select * from
pet where user = user2.id union ... union select * from pet where user
= userN.id.
Regroup children by parentPk(you can use lodash or underscore.js functions to do it) Ex:
users.forEach(function(user){
user.pets = _.filter(pets,function(pet){
return pet.user === user.id;
});
});
All queries are tested on sparql virtuso endpoint
I want to find the categories of two dbpedia subject like here Bharatiya_Janata_Party and New_Delhi. I want to match how the categories of these are similar to each other.
As here in the first query i got the categories of Bharatiya_Janata_Party.
In the Second query i got the categories of New_Delhi.
Now I want to match the result of category of Bharatiya_Janata_Party to that of New_Delhi. Like here
Nationalist_parties---New_Delhi
Nationalist_parties---New_Delhi_district
Nationalist_parties---Populated_places_established_in_1911
Nationalist_parties---Capitals_in_Asia
Nationalist_parties---Capitals_in_Asia
Nationalist_parties--Planned_capitals
Political_parties_established_in_1980---New_Delhi
Political_parties_established_in_1980---New_Delhi_district
.....
....
..
..
I have fired a query III for making match between Nationalist_parties---New_Delhi. I got a match at level 4((^skos:broader){0,4}).
Similarly Again I have to do for Nationalist_parties---New_Delhi_district.
The real problem is that i want to combine these 3 queries so that i may get the direct result in a tabular form. Is there any way to automate the whole process.
Query I:
SELECT *
WHERE {
dbpedia:Bharatiya_Janata_Party dcterms:subject ?x
}
Result of Query I:
dbpedia.org/resource/Category:Nationalist_parties
dbpedia.org/resource/Category:Political_parties_established_in_1980
dbpedia.org/resource/Category:Conservative_parties_in_India
dbpedia.org/resource/Category:Hindu_political_parties
dbpedia.org/resource/Category:Hindutva
dbpedia.org/resource/Category:Bharatiya_Janata_Party
dbpedia.org/resource/Category:1980_establishments_in_India
Query II:
SELECT *
WHERE {
dbpedia:New_Delhi dcterms:subject ?x
}
Result of Query II:
dbpedia.org/resource/Category:New_Delhi
dbpedia.org/resource/Category:New_Delhi_district
dbpedia.org/resource/Category:Populated_places_established_in_1911
dbpedia.org/resource/Category:Capitals_in_Asia
dbpedia.org/resource/Category:Indian_capital_cities
dbpedia.org/resource/Category:Planned_capitals
dbpedia.org/resource/Category:Urdu-speaking_countries_and_territories
QUERY III:
select distinct ?super where {
?super (^skos:broader){0,4} category:Nationalist_parties, category:New_Delhi
}
Result:
dbpedia.org/resource/Category:Government-related_organizations
dbpedia.org/resource/Category:Government
First Match at level 4 with 2 Super Classes
P.S: It is not necessary that the other query will match at (^skos:broader){0,4}. So i am manually firing the above query from (^skos:broader){0,0} and incrementing as (^skos:broader){0,1}->(^skos:broader){0,2)...to the first match.
select distinct ?super where {
?super (^skos:broader){0,6} category:Nationalist_parties, category:New_Delhi_district
}
Result:
dbpedia.org/resource/Category:Categories_by_topic
dbpedia.org/resource/Category:Government
dbpedia.org/resource/Category:Categories_by_parameter
dbpedia.org/resource/Category:Political_geography
First Match at level 6 with 4 Super Classes
===================================
Combining these 3 queries i want this type of result in a tabular form:-
==================================
**CategoryI(QueryI---Category(QuesryII)---Level --count matches*
Nationalist_parties---New_Delhi---------------------------- 4------ 2
Nationalist_parties---New_Delhi_district-------------------6--------4
Nationalist_parties---Populated_places_established_in_1911
Nationalist_parties---Capitals_in_Asia
Nationalist_parties---Capitals_in_Asia
...
.....
....
Please help me to automate and combine the above query. I have read several posts but not able to figure it how.