Reputation: 1765
I'm struggeling with something that is perhaps very simple:
I have an array of objects, where each object is Date+Value.
Using AQL I want to add a new date+value object to the array if it does not have one, or update the value with a new value (adding to existing value) if there's already an object w. the same date in the array.
New objects will always have a newer date than existing, so the array should be sorted.
Starting with
[[date:"2024-10-05",value:2},{[date:"2024-10-06",value:1}]
Adding for {date:"2024-10-07",value:2}
, since there's no entry for that date, the resulting array should be:
[[date:"2024-10-05",value:2},{[date:"2024-10-06",value:1},[date:"2024-10-07",value:2}]
After that, again adding {date:"2024-10-07",value:2}
should update that one, so 2 becomes 4:
[[date:"2024-10-05",value:2},{[date:"2024-10-06",value:1},[date:"2024-10-07",value:4}]
The values in the new object comes in as parameters @newDate, @valueAdd
.
It is specifically the add-or-update thing that I find difficult to understand how to do with AQL. I'm going to do this for a lot of arrays, each vertice has such an array, but for simplicity I left this out, as that is just a loop within a loop.
Although I feel this isn't "correct" using date-strings as keys, I have this working alternative using an object instead of an array.
Instead of:
[[date:"2024-10-05",value:2},{[date:"2024-10-06",value:1},[date:"2024-10-07",value:4}]
Use an object with date-strings as keys (since I don't want duplicates for the same day, in that case want to update):
{"2024-10-05":2, "2024-10-06:1,"2024-10-07:4}
Then I can easily do
let x = HAS(MyObject,@today) ? MyObject[@today] : 0
let xx = MERGE(NOT_NULL(MyObject,{}), {@today: x+@add})
UPDATE MyVertice WITH {MyObject: xx} IN MyCollection
This will add/insert like expected.
The problem now becomes fetching the latest value. With an array I could just do theArray[-1]
to get the latest, but with an object I need to find the "latest key", that is the highest date. Luckily ArangoDb has a function ATTRIBUTES which has a sort parameter ATTRIBUTES(document, removeSystemAttrs, sort) → strArray
, and ISO-dates can be sorted alphabetically, so I can do:
let MyVertice = DOCUMENT("MyCollection/A")
// some NOT_NULL logic removed to keep short
let latestDate = ATTRIBUTES(MyVertice.MyObject, true, true)[-1]
return MERGE(MyVertice , {LatestValue:{[latestDate]: NOT_NULL(MyVertice.MyObject[latestDate],0)}})
Upvotes: 1
Views: 28