OrientDB: creating edge from parent to child - orientdb

I am new to a graph database. I am very sure that the answer should be simple as one or two command lines.
I have very simple schema. Person and Email class. There are edges between Person and Email, SendFrom and SendTo. I want to create edges between Person vertices which is joined by the same email.
For instance, if person A sends an email to person B. I want to create an edge between A and B, and increment count property of the edge.
I tried something like, CREATE EDGE FROM (SELECT in() from Email) TO (SELECT out() from Email). Since I am using pyorient, a python driver for OrientDB, this could be done in Python script, or just SQL like language.
I will edit my post, if you need more information. Just let me know.

I tried with this structure
This is the graph.
I used this javascript function.
var g=orient.getGraph();
var c=g.command("sql","select in('SendFrom')[0].#rid as SF, out('SendTo')[0].#rid as ST from email");
for(i=0;i<c.length;i++){
var p1=c[i].getProperty("SF");
var id1=p1.toString();
id1=id1.substring(id1.lastIndexOf("[")+1,id1.lastIndexOf("]"));
var p2=c[i].getProperty("ST");
var id2=p2.toString();
id2=id2.substring(id2.lastIndexOf("[")+1,id2.lastIndexOf("]"));
g.command("sql","create edge e from " + id1 + " to " + id2 );
}
This is the new structure
and this is the new graph
Hope it helps.

This is just a Python version of Alessandro's answer using pyorient.
cluster_id = client.command("create class Email_ex extends E")
rst = client.query("select in('SendFrom') as SF, out('SendTo') as ST " +
"from Email limit -1")
for email in rst:
for sf in email.SF:
for st in email.ST:
edge_ex = client.command("create edge Email_ex from " +
str(sf) + " to " + str(st));

Related

Making a copy of record without edges

Is there a way to make a copy of an arbitrary OrientDB record without its edges? I modified an original command (from the docs) for copying records and added fetchplan to it, but it does not work (frankly speaking to me it looks like there's a problem parsing this particular command, but hopefully im wrong)
This one executes fine, but edges remain:
insert into Test from select from Test where #rid=#102:119 fetchplan in_*:-2 out_*:-2
This one gives an error:
insert into Test from (select from Test where #rid=#102:119 fetchplan in_*:-2 out_*:-2)
com.orientechnologies.orient.core.command.OCommandExecutorNotFoundException: Cannot find a command executor for the command request: sql.(SELECT FROM Test WHERE #rid = #102:119 FETCHPLAN in_*:-2 out_*:-2)
also tried smth like
insert into Test content (select #this.toJSON('fetchPlan:in_*:-2 out_*:-2') from Test where #rid=#102:119)
but that doesn't work either. Any thoughts? I'm on Orient 2.1.x
As workaround you can use this javascript function with one parameter (id)
var g=orient.getGraph();
var b=g.command("sql","select #this.toJSON('fetchPlan:in_*:-2 out_*:-2') as json from "+ id);
if(b.length>0){
var query="insert into Test content " + b[0].getProperty("json") ;
var myVertex=g.command("sql",query);
g.commit();
return myVertex;
}
Using the following command
select expand(result) from (select yourFunction(#102:119) as result)
Here's how to select all vertices (V) that have no incoming or outgoing edges:
select from (select #this, bothE().size() as n from V) where n = 0
I tried your query and I have the same problem.
I solved it in this way:
insert into Test from select <property-name> from Test where #rid=#102:119
If you want use it with fatchplan try this:
insert into Test from select <property-name> from Test where #rid=#102:119 fetchplan in_*:-2 out_*:-2
Hope it helps.
Regards,
Michela

Incomplete data while fetching through Named Query JPA2.0

I have an entity named ReqestDetail and done association and mapping as below snippet:
#ManyToOne
#JoinColumn(name="STATUS_C")
private StatusCode statusCode;
//bi-directional many-to-one association to RequestAddressDetail
#OneToMany(mappedBy="requestDetail")
private List<RequestAddressDetail> addressDetails;
I have created below Named Query to fetch the details on the basis of address.
TypedQuery<RequestDetail> query = em.createQuery( "SELECT t FROM RequestDetail t" +
" LEFT JOIN t.employeeDetail e " +
" LEFT JOIN t.addressDetails ao " +
" LEFT JOIN t.addressDetails ad " +
" WHERE (e.employeeI IN ( :employeeIds ) ) AND " +
" (ao.postI = :postO AND ao.addressTypeC = :addressTypeO " +
" AND ad.postI = :PostD AND ad.addressTypeC = :addressTypeD )" ,
RequestDetail.class );
However, when I call query.getResultList(), it is only giving me data of RequestDetail Entity but not of the mapping joins I have mentioned in that entity.
Please advise...
why do you think it should give you some joined objects? Your candidate for the query is RequestDetail, so it gives that. If you did a JOIN FETCH then you can fetch other fields, but you haven't done that (so change those LEFT JOIN to LEFT JOIN FETCH) - a JOIN (without FETCH) is simply a convenience way of forming the query.. Alternatively you could set the entity graph to fetch, or set the fetch on the field itself if you wanted those fetching

jpa query for arithmetic operation on columns

I am somewhat new to jpa. I have created a few simple queries. But now i have a problem with a simple query. I have an entity Payment with 3 columns(Id,Amount1,Amount2).
Now i want to find all the rows from Payment where Amount1+Amount2 is greater than somevalue.I tried something like:
Query query = getEntityManager().createQuery(
"Select p from Payment p WHERE p.Amount1 + p.Amount2 >' " + someamount +" ' ");
But it is not working. I tried using SUM also but that is only one column.
Can anyone help me with this.
Thanks.
Assuming your entity is properly defined, the following query should work just fine:
final BigDecimal threshold = BigDecimal.valueOf(1000);
TypedQuery<Payment> query = getEntityManager().createQuery(
"SELECT p FROM Payment p WHERE p.Amount1 + p.Amount2> :value",
Payment.class);
query.setParameter("value", threshold);
List<Payment> results = query.getResultList();

UPDATE and JOIN with JPQL

Tutorials and samples about JPQL always deal with SELECT statement and sometimes, simple UPDATE statements. I need to update a table with a join.
I have simplified my env :
KEY
= id
- counter
APPLET
= id
! key_id (1-1)
DEVICE
= id
! applet_id (1-1)
! user_id (1-n)
USER
= id
- login
A device has a unique applet, which has a unique keyset. But an user can own several devices.
I need to reset the counter of every KEY attached to the USER login "x".
I tried some syntax with UPDATE and JOIN, without success. Any clue ?
Thank you.
What did you try and what error did you get? What is your object model?
Perhaps something like,
Update Key k set k.counter = 0 where exists (Select u from User u join u.devices d where u.login = "x" and d.applet.key = k)
See,
http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#Update
You could also select the objects and reset the counter in memory and commit the changes.
JPQL does not support join operations in bulk update operations.
When you edit query, nativeQuery = true, you can join.
Query should be written according to the fields in the database.
#Transactional
#Modifying
#Query(nativeQuery = true,
value = "UPDATE Team t" +
" SET current = :current " +
" FROM " +
" members," +
" account" +
" WHERE " +
" members.members_id = t.members_id " +
" AND members.account_id = :account " +
" AND t.current = :current_true ")
int updateTeam(
#Param("current") String current,
#Param("account") Long account,
#Param("current_true") Integer current_true);

TSQL Summary by account, what is the cleanest way to approach this?

I am trying to total by account, the expenses & income per account. There are multiples of both the income & the expenses per account. I am struggling with this as am still learning SQL and thought that someone else likely has already addressed this? I sure would appreciate the help!
I know that this SQL server code is not correct but it at least gives a bit clearer picture of what I am attempting to do.
IF(SELECT(OBJECT_ID('TEMPDB..#Total'))) IS NOT NULL DROP TABLE #Total
declare #Expenses decimal(13,2),
#income decimal(13,2)
set #expenses = sum(EXP_CHILD_CARE_AMOUNT)
+ sum(EXP_FOOD_AMOUNT)
+ sum(EXP_LIFE_INSURANCE_AMOUNT)
+ sum(EXP_TRANSPORTATION_AMOUNT)
+ sum(EXP_TUITION_AMOUNT)
+ sum(EXP_USER_2_AMOUNT)
+ sum(EXP_USER_3_AMOUNT)
+ sum(EXP_UTILITIES_AMOUNT)
set #income = (sum(NET_PAY_AMOUNT)
+ sum(OTHER_INCOME_AMOUNT)
SELECT F.LOAN_NUMBER, #Income, #Expenses
INTO #Total
FROM OPENQUERY(SvrLink, '
SELECT F.Account, #Income, #Expenses
FROM finances F
inner join account a on(a.Account = f.Account)
where a.balance > 0
FETCH ONLY WITH UR ')
...ok, assuming that some fields are grouped into the same table (if not you'll just have to write the joins), you just need 1 query. (I wish all languages were as concise...)
#AccountId is your desired account id.
SELECT l.LOAN_NUMBER, l.AccountId,
(SELECT sum(EXP_CHILD_CARE_AMOUNT) + sum(EXP_FOOD_AMOUNT) +
sum(EXP_LIFE_INSURANCE_AMOUNT) + sum(EXP_TRANSPORTATION_AMOUNT) +
sum(EXP_TUITION_AMOUNT) + sum(EXP_USER_2_AMOUNT) +
sum(EXP_USER_3_AMOUNT) + sum(EXP_UTILITIES_AMOUNT)
as ExpenseTotal FROM Expenses_Guessing_The_Table_Name
WHERE AccountId = #AccountId) as ExpenseTotal,
(SELECT sum(NET_PAY_AMOUNT) + sum(OTHER_INCOME_AMOUNT) as IncomeTotal
FROM Income_Guessing_The_Table_Name
WHERE AccountId = #AccountId) as IncomeTotal
FROM Loans l
WHERE l.AccountId = #AccountId AND l.Balance > 0