邮件信息的组成部分
- folder: 位置信息
收件箱
发件箱
- Message_ID: 邮件的ID
- subject: 主题
- sessionSubject 会话主题。去除主题的前缀,如
回复
Re
答复
自动回复
自动答复
-
References
:
当回复(全部回复)/转发一个邮件的时候,当前邮件回在头信息中添加References
,参照Message_ID
。多轮回复,邮件有多个References
.Root引用在第一个位置 -
Default References
(subject + 所有参与者)为组合生产一个定义的
Default References
,这个always有。
会话的聚合逻辑
聚合的原则:
将相同【会话主题】和具有【引用关系】邮件组成一个会话模式
* 引用关系包含邮件References和Default Reference
几种情况的说明:
-
无主题的不聚合
-
转发的虽然有引用,但是不聚合,从会话中脱离出来。因为主题发生了变化。“回复:你好”的会话主题是“你好”,而“转发:你好”的会话主题是“转发:你好”
具体步骤:
数据准备
-
拉取所有的
收件箱
邮件 -
按条件拉取
发件箱
,找跟收件箱的关系前提,必须
收件箱
有的【会话主题】- 被
收件箱
邮件引用 - 引用
收件箱
- 和
收件箱
有相同的邮件引用 & 收件时间 < 发件时间 - 和
收件箱
有相同的自定义引用 & 邮件引用不存在 & 收件时间 < 发件时间
- 被
Query.sql
SELECT
SUBJECT,
NAME,
common_subject,
message_id,
session_id session_id,
reference,
send_time
FROM
t_mail t
WHERE
EXISTS (
SELECT
1
FROM
t_mail t2
WHERE
t. NAME = 'INBOX' -- 【INBOX】所有邮件
OR (
t.common_subject = t2.common_subject
and (
(
t.message_id = t2.reference -- 被INBOX引用的【发件箱】邮件
AND t2.`name` = 'INBOX'
)
OR
(
t.session_id = t2.session_id -- INBOX时间之后,【发件箱】能组队的
AND t2.`name` = 'INBOX'
AND t.send_time > t2.send_time
And t2.reference is null
)
or (
t.reference = t2.message_id
AND t2.`name` = 'INBOX'
)
OR (
t.reference = t2.reference -- INBOX时间之后,【发件箱】是引用的
AND t2.`name` = 'INBOX'
AND t.send_time > t2.send_time
)
)
)
)
ORDER BY
send_time DESC;
- 所有邮件按照发件顺序倒序排
数据聚合
遍历所有邮件
1. 有主题吗?没有主题自己单独一个会话。否则往下继续执行2
-
邮件引用,有没有引用其他邮件
- 有引用,看有没有以【Reference ID+会话主题】为key的空间,如果有在尾部加入,没有自己开辟
- 没有引用,继续3
-
邮件被引用
- 有没有【Message_ID + 会话主题】的空间,有直接加入
– 没有继续详细执行4
- 自定义引用
- 看有没有以【自定义引用+会话主题】为key的空间,如果有在尾部加入,没有自己开辟
foreach.java
list.forEach(mailEntity -> {
if (StringUtils.isBlank(mailEntity.getCommonSubject())) { //无主题独占会话
sessionMap.put(String.valueOf(IDUtils.genItemId()), Sets.newLinkedHashSet(mailEntity));
return;
}
String reference = mailEntity.getReference();
// 引用方
if (reference != null) {
Set<MailEntity> line = sessionMap.get(reference + ":" + mailEntity.getCommonSubject());
if (line == null) {
line = Sets.newLinkedHashSet();
sessionMap.put(reference + ":" + mailEntity.getCommonSubject(), line);
}
line.add(mailEntity);
return;
}
// 被引用方
String messageId = mailEntity.getMessageId();
Set<MailEntity> line = sessionMap.get(messageId + ":" + mailEntity.getCommonSubject());
if (line != null) {
line.add(mailEntity);
return;
}
// 自建引用
String sessionId = mailEntity.getSessionId();
line = sessionMap.get(sessionId + ":" + mailEntity.getCommonSubject());
if (line != null) {
line.add(mailEntity);
return;
} else {
line = Sets.newLinkedHashSet();
sessionMap.put(sessionId + ":" + mailEntity.getCommonSubject(), line);
line.add(mailEntity);
}
});