Transitive Clousure in OrientDB query language - orientdb

Suppose I have a vertex class called PERSON and and an edge Class called father:
CREATE CLASS PERSON EXTENDS V
CREATE CLASS father EXTENDS E
Suppose that I populated PERSON with some records. I also populated father with some records that connect certain records in PERSON to some others records of PERSON (this simply model who is father of who)
I would like to know how the following query would look like in OrientDB?
Find all ancestors of the Person, say p1 (with rid=#10:1)?

create class Person extends V
create class Father extends E
create vertex Person set name = 'grandfather' #12:0
create vertex Person set name = 'father' #12:1
create vertex Person set name = 'person' #12:2
create edge Father from #12:0 to #12:1
create edge Father from #12:1 to #12:2
I believe this is the situation described above. You can:
select from (
traverse in('Father') from #12:2
) where #rid <> #12:2
This will return all the ancestors of the person (#12:2).

Related

Orientdb 3.0 How to use map field for dynamic attributes without loosing existing data

How I am trying to use map to store multiple key value properties. the problem I see is that it doesn't let me store existing data, it overrides data everytime I tried to set a new property.
Create VERTEX Person extends V;
CREATE CLASS Person EXTENDS V;
CREATE PROPERTY Person.name STRING (MANDATORY TRUE, MIN 3, MAX 50);
Create VERTEX Person set name="test";
update ( SELECT from Person where name="test") SET mapField=
{"property1":mapField.property1+10};
set property1 into map, and update it, works just fine.
update ( SELECT from Person where name="test") SET mapField=
{"property1":mapField.property1+30};
select from Person;
Set another property "property2", now I loose the property1.
update ( SELECT from Person where name="test") SET mapField=
{"property2":mapField.property2+10};
select from Person;
is ther a way I can retain previous property and make this work still?
Thanks
Hari
This should do the trick:
update ( SELECT from Person where name="test")
SET mapField.property1 = mapField.property1 + 30;
In V 2.2 there was also an UPDATE PUT option, ie.
update ( SELECT from Person where name="test")
PUT mapField = property1, eval('mapField.property1 + 30');
but it's not supported anymore (and it's definitely ugly)

OrientDB how to match multiple related classes

I am trying to write a MATCH statement to pull related data.
CREATE CLASS Member EXTENDS V;
CREATE CLASS DirectVolumes EXTENDS V;
CREATE SEQUENCE dvSequence TYPE ORDERED;
CREATE CLASS GroupVolumes EXTENDS V;
CREATE SEQUENCE groupVolumesSequence TYPE ORDERED;
CREATE CLASS GenerationVolumes EXTENDS V;
CREATE SEQUENCE genGroupVolumesSequence TYPE ORDERED;
CREATE SEQUENCE memberIdSeq TYPE ORDERED;
CREATE VERTEX Member SET id=sequence('memberIdSeq').next();
CREATE VERTEX DirectVolumes set id=sequence('dvSequence').next();
CREATE VERTEX GroupVolumes set id=sequence('groupVolumesSequence').next();
CREATE VERTEX GenerationVolumes set id=sequence('genGroupVolumesSequence').next();
CREATE EDGE OWNS_DV_CURRENT FROM (SELECT FROM Member WHERE id = 1) TO (select from DirectVolumes where id = 1);
CREATE EDGE OWNS_PG_CURRENT FROM (SELECT FROM Member WHERE id = 1) TO (select from GroupVolumes where id = 1);
CREATE EDGE OWNS_GG_CURRENT FROM (SELECT FROM Member WHERE id = 1) TO (select from GenerationVolumes where id = 1);
Now I want Member, andOWNS_DV_CURRENT, OWNS_PG_CURRENT, OWNS_GG_CURRENT edges data together. I have removed properties for simplicity.
What is the right way to do this with a MATCH? I didn't figure out how to fetch multiple related Classes. query seems ok but it returns 0 I think it is looking for OWNS_PG_CURRENT on top of OWNS_DV_CURRENT and not on Member itself.
select from (MATCH {class: Member, as:member}.out("OWNS_DV_CURRENT"){as:dv}.out("OWNS_PG_CURRENT") {as: pg} RETURN member, dv,pg)
Try this:
MATCH
{class: Member, as:member}.out("OWNS_DV_CURRENT"){as:dv},
{as:member}.out("OWNS_PG_CURRENT") {as: pg}
RETURN member, dv,pg

JPQL Filtering child

I am using spring data jpa:
What is the best way to filter child object on the parent.
on my below example
I want Parent objects which has active childs, also wanted only active childs as list with parent
#Query(select distinct p from Parent p inner join p.child c where c.active=:active)
Page<Parent> getAllPArents(#Param("active") int active);
#Entity
Parent{
#OneToMany(fetch=FetchType.LAZY)
List<Child> child;
}
#Entity
Child{
#ManyToOne
Parent parent;
}
I had exactly the same problem and it took me a while to find out how this works. The child list will be filtered when you add FETCH after your JOIN like this:
SELECT p FROM Parent p JOIN FETCH p.child c WHERE c.active=:active
After spending lot of time, I could not find any solution to filter the child while querying the parent.
I decided to change the database structure so that I will be able to query child that I wanted. Added another filed/property that can put child into different categories. When querying child using unique criteria that will give me only the child I needed, also gave me the parent which I needed too.
I found the way to do this:
You can use the #Where annotation to filter the childs of a one to many or a many to many relationship.
public class Parent {
#OneToMany(mappedBy="Parent")
#Where(clause = "active = 1") //In case of a boolean but it can be a LIKE, a comparator...
private Set<Child> childs; //This gets filled with pets with a name starting with N
//getters & setters
}

Spring data JPA JPQL query on child property

I am using spring-data jpa. When querying parent object with child object property,I was expecting parent with aggregated child objects.I have OneToMany relation between User and Phone. Just typing some part of code.
#Query(select u from User u inner join u.phone ph where ph.active=:active)
Page<User> getAllUsers(#Param("active") int active);
#Entity
User{
#OneToMany(fetch=FetchType.LAZY)
List<Phone> phone;
}
#Entity
Phone{
#ManyToOne
User user;
}
My query returns multiple User object based on active phone quantity. I was expecting one User object and all aggregated phone object in the list as part of User object. Is my assumption is wrong or am I doing something wrong?
Try:
#Query(select distinct u from User u inner join u.phone ph where ph.active=:active)
Page<User> getAllUsers(#Param("active") int active);

JPA mapping of multiple attributes of the same type

I am learning JPA (2.0) and I would like to understand how to properly map multiple attributes of the same class type. For instance, pretend I have a model:
#Entity
class Person {
String name;
int age;
// getters/setters
}
#Entity
class Family {
Person dad;
Person mom;
List<Person> children;
// getters/setters
}
How can I properly map mom and dad attributes?
Thanks and sorry if it is too basic. Couldn't find an answer anywhere.
The fact that you have two instances doesn't change anything.
You map dad and mom each as a ManyToOne association, and there will be two join columns in the family table: one for dad and one for mom.
You map children as a OneToMany (assuming a child can only be a child in one family), and there will be either a join table between Family and Person (the default for a unidirectional OneToMany), or a join column in the Person table referencing the family table (the default for a OneToMany bidirectional association).