Best practices with TimedValue

#1

I have seen and used many times TimedValue and TimedValueHistory (or its equivalent TimedIntervalValue and TimedIntervalValueHistory). I would like to know how to best use it. More precisely I have seen two different approaches:

1st Approach

type MyTimedValue mixes TimedValue, String

entity type MyTimedValueSet mixes TimedValueHistory<MyParent>, String
(or mixes TimedValueHistory<MyParent>, MyTimedValue ?)

entity type MyParent {
..
   @db(timedValueHistoryField='myTimedValueSet')
   myTimedValue: MyTimedValue
   
   @db(order='descending(toUTC(timestamp))')
   myTimedValueSet: [MyTimedValueSet] (parent)
}

(I get the idea but do not understand the naming conventions: according to me a a set of timed value would be a collection of timed values, not a collection of timed value set.)

Then during data load we would directly load through MyParent:

type MyTransform mixes MyParent transforms MyCanonical {
   ....
   myTimedValue: ~ expression '{value: .., timestamp: ..}'
}

and that would automatically update myTimedValueSet.

2nd Approach:

entity type MyTimedValueHistory mixes TimedValueHistory<MyParent>, String

entity type MyParent {
...

   @db(order='descending(toUTC(timestamp))')
   myTimedValueHistory: [MyTimedValueHistory] (parent)
}

Then during data load we would load through MyTimedValueHistory:

type MyTransform mixes MyTimedValueHistory transforms MyCanonical {
   timestamp: ~ expression ..
   value: ~ expression ..
   parent: ~ expression ..
}
1 Like
#2

In addition to the data load each approach also leads to different way of creating metrics. Again, which option is preferred?

1st Approach

{
id: "MyTimedValue_MyParent",
name: "MyTimedValue",
path: "myTimedValue",
expression: "value"
}

Note: Please confirm that using the timedValueHistoryField here will automatically go get the myTimedValueSet field and change the value over time according to the history.
Question: How do we specify the treatment applied to ‚Äúvalue‚ÄĚ?

2nd Approach

{
id: "MyTimedValue_MyParent",
name: "MyTimedValue",
path: "myTimedValueHistory",
expression: "value"
}

Question: Would this work? How do we specify the treatment applied to ‚Äúvalue‚ÄĚ?

Persistence of duplicate value objects in TimedValueHistory type
#3

myTimedValueSet is history of data points with timestamp and value, myTimedValue is the latest value…

Notice, in the first approach, you are sending the latest time value with the parent, Platform will do the needful to see if there is any change in value since the last and record the change if needed in the TimedValueHistory.

In second approach user needs to do if there is a change in value and create record, if that is not done by user, TimedvalueHistory could have duplicates. ( will confirm after checking with @trothwein if this is true). and parent will be updated with latest value on field myTimedValue.

#4

For Metric definition,
if you need declare different treatment, you need to use tsDecl options. not expression.

if you think myTimedValueHistory has duplicates, you need to handle with ‚Äútreatment‚ÄĚ.

#5

I prefer the first method when my fetches frequently need the current (latest) value ‚Äúinline‚ÄĚ with other fields in MyParent. Often, we want the latest value for presenting in user interfaces (like grid objects).

A common pattern is to present a list of MyParent objects in a grid - and then allow a user to select ONE (or a few) instances of interest from that grid one object. In that grid, we might show the current value - and this needs to be inexpensive to fetch.

Another UI component (usually immediately below the initial grid) then presents more information about the currently selected item… which could be, for example, a plot of historical values for MyTimedValueSet.

For the above pattern described, populating the initial grid performs better than having to traverse two types, and perhaps ordering values in MyTimedValueSet…to present the current value because you have to do this repeatedly for every instance of MyParent in the grid. (long winded…hope that makes sense)

Also, thinking about best practices ‚Äď I don‚Äôt like calling the historical values as a SET. Set to me means that the values are unordered (think relational theory). Instead, I think MyTimedValueHistory as being more appropriate naming scheme because History implies time based ordering‚Ķ and this also feels way more natural (to me anyway) since the annotation is @db(timedValueHistoryField‚Ķ)

that is:

@db(timedValueHistoryField=‚ÄėmyTimedValueHistory‚Äô)

reads more naturally to me than,

@db(timedValueHistoryField=‚ÄėmyTimedValueSet‚Äô)

but that’s just me.

1 Like