Store accum value to vertex attribute

Hi team,
I want to store accumulated value in vertex attribute. For example, let’s consider a Profile vertex with age attribute : Profile(PRIMARY_ID profile_id INT, age INT, dob DATETIME)
I want to calculate age of profile and then update the value in “age” attribute using below mentioned logic

CREATE QUERY calculate_age(/* Parameters here /) FOR GRAPH test {
/
Write query logic here /
SumAccum @diff_in_seconds;
SumAccum @age;
int seconds_in_year = 31557600;
start = {Profile.
};
all_profiles = select s from start:s where s.profile_id<3 ACCUM s.@diff_in_seconds += datetime_diff(now(), s.dob);
all_profiles = select s from start:s where s.profile_id<3 Accum s.@age+= s.@diff_in_seconds/seconds_in_year
post-accum s.age = s.@age;
print all_profiles[all_profiles.dob, all_profiles.@diff_in_seconds, all_profiles.@age, all_profiles.age];

PRINT “calculate_age works!”;
}

Output of first run:

[
{
“all_profiles”: [
{
“attributes”: {
“all_profiles.@age”: 41,
“all_profiles.@diff_in_seconds”: 1306684869,
“all_profiles.age”: 0,
“all_profiles.dob”: “1980-07-13 00:00:00”
},
“v_id”: “2”,
“v_type”: “Profile”
},
{
“attributes”: {
“all_profiles.@age”: 46,
“all_profiles.@diff_in_seconds”: 1462896069,
“all_profiles.age”: 0,
“all_profiles.dob”: “1975-08-01 00:00:00”
},
“v_id”: “1”,
“v_type”: “Profile”
}
]
},
{
““calculate_age works!””: “calculate_age works!”
}
]

Output of Second run:

[
{
“all_profiles”: [
{
“attributes”: {
“all_profiles.@age”: 41,
“all_profiles.@diff_in_seconds”: 1306684900,
“all_profiles.age”: 41,
“all_profiles.dob”: “1980-07-13 00:00:00”
},
“v_id”: “2”,
“v_type”: “Profile”
},
{
“attributes”: {
“all_profiles.@age”: 46,
“all_profiles.@diff_in_seconds”: 1462896100,
“all_profiles.age”: 46,
“all_profiles.dob”: “1975-08-01 00:00:00”
},
“v_id”: “1”,
“v_type”: “Profile”
}
]
},
{
““calculate_age works!””: “calculate_age works!”
}
]

I can see in the output that s.@diff_in_seconds and s.@age are being calculated correctly but value of attribute age is not getting updated. It remains 0 ,i.e., s.@age=41 but s.age remains 0 during the first run. If I run same query again, s.age becomes 41. I am wondering why attribute “age” doesn’t get updated with the value of “@age” in first run but it does get updated in second run. Also, I’ve seen that value of accum variable from previous run gets stored in “age” attribute of current run. How come second run of same query receives value from previous run? Looks like value calculated in accum variable is being cashed somehow.

currently, any graph element (vertex/edge) persistent attribute update within a query will not be seen until that query is complete.

That explains why the second invocation of the query see the attribute change.

We are in the process to add query block level commit.

4 Likes

Thanks mingxiwu for ur reply. Yes, the changes made by a query don’t reflect until it gets completed. I am wondering if there is any solution/roundabout (except accumulators) of this issue for now. I am trying to create new edges and then traverse them in the same query. It doesn’t work for the reason that you stated in your reply. I tried breaking the problem into multiple subqueries : subquery1 for creating the edges and subquery2 for traversing those edges and calculating the score, then calling both these queries in main query as stated below :
subquery1 : inserts edge between segment and profile. Vertex_Profile:s-(belongs_to:e)-Vertex_Segment.
subquery2 : calculates score by traversing “belongs_to” edge and then counting number of profile belonging to segment.
main_query : run subquery1(), then subquery2().
I was trying to check if subquery2 can access the newly created edges by subquery1 but it didn’t work.

Since the addtion of query level block commit is under progress, is there any possible way to achieve the above functionality for now?
I was also thinking about using accumulators and nested for loops but it didn’t seem to be an optimal solution.

Thanks,
Mohit

Accumulators and loops within a single query are probably the best way to go about this, even if it may seem sub-optimal. Instead of updating the age attribute for every query run, I would simply store and refer to it through a vertex-attached accumulator within a single call.

I understand that this may not play nicely with your intended query calling structure (calculating new age for every run since the query was last run). Another alternative might be to work with subqueries that pass the last updated age to one another so that the internal graph structure is never relied on to grab the current age of a profile.

1 Like