I have dataframe sorted by user_id and timestamp and it looks like the following:
| user_id | timestamp |
|---|---|
| 1 | 1661941403 |
I want to generate unique session_id for each rows by following rules:
- If diff between two rows is less than 5 min (and user_id is the same) then it is same session_id
- Otherwie if diff between two timestamps is more than 5 min (or user_id is different) then use session_id + 1
So my first attempt is to map dataframe to another dataframe, and use LongAccumulator to get new session_id, e.g.
val sessionId: LongAccumulator = sparkSession.sparkContext.longAccumulator("sessionId")
df.select(col("user_id"), col("timestamp"), lag("user_id", 1, 0), lag("timestamp", 1, 0))
.rdd.map(
row => {
val userId = row.getLong(0)
val time = row.getLong(1)
val prevTime = row.getLong(2)
val prevUserId = row.getLong(3)
if (prevTime != 0 && prevUserId != 0) {
if (userId == prevUserId && ((time - prevTime) / 60 > 5)) {
sessionId.add(1)
} else if (userId != prevUserId) {
sessionId.add(1)
}
}
(userId,time,sessionId.value)
}).toDF("user_id", "time", "session_id")
However, as far as I understood it is a wrong idea to use accumulator. So what can I do?