我们有一个应用程序可以捕获用户所做的搜索。由于我们搜索的性质(我们在几个字符后提供结果)和人们键入的速度,我们得到了每个搜索/信件的日志条目。这看起来像这样:
(看起来像是圣诞树上下的一面…)
我们在内部需要这些数据来计算搜索次数(又称api调用),但对于向客户报告的情况,报告“一半”查询并不是很好。
我正在寻找一种方法,可以将这些行折叠成一个具有最长/最后一个搜索项的行。
有一个陷阱:一个用户(cid)可以在一个会话中进行1次以上的搜索,但是如果我们查看时间戳,我们可以将其分开。。
必须是这样的:
1) 将间隔不超过2秒的行分组
2) 按长度排序(或最后一个)查询以获取最终查询
3) 按术语分组,计算术语用于报告的频率
数据作为文本:
2019-12-09 2019-12-09 12:58:45 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum cleaner
2019-12-09 2019-12-09 12:58:45 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum cleane
2019-12-09 2019-12-09 12:58:44 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum clean
2019-12-09 2019-12-09 12:58:43 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum clea
2019-12-09 2019-12-09 12:58:43 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum cle
2019-12-09 2019-12-09 12:58:42 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum cl
2019-12-09 2019-12-09 12:58:41 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum c
2019-12-09 2019-12-09 12:58:40 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuum
2019-12-09 2019-12-09 12:58:39 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacuu
2019-12-09 2019-12-09 12:58:38 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vacu
2019-12-09 2019-12-09 12:58:37 5dea585477c94502b52c43fb 92cd6cef-3ed8-4416-ac2d-cc347780b976 search 1 search query vac
2019-12-09 2019-12-09 12:58:15 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue widget
2019-12-09 2019-12-09 12:58:14 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue widge
2019-12-09 2019-12-09 12:58:13 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue widg
2019-12-09 2019-12-09 12:58:12 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue wid
2019-12-09 2019-12-09 12:58:12 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue wi
2019-12-09 2019-12-09 12:58:11 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue w
2019-12-09 2019-12-09 12:58:10 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blue
2019-12-09 2019-12-09 12:58:09 5dea585477c94502b52c43fb 9b41fb1d-59d2-4a12-8974-b2261b2fe484 search 0 search query blu
2019-12-09 2019-12-09 12:57:38 5dea585477c94502b52c43fb f96305d9-590b-4a10-95a2-2d49a9fc63a3 search 1 search query widget
2019-12-09 2019-12-09 12:57:37 5dea585477c94502b52c43fb f96305d9-590b-4a10-95a2-2d49a9fc63a3 search 1 search query widge
2019-12-09 2019-12-09 12:57:36 5dea585477c94502b52c43fb f96305d9-590b-4a10-95a2-2d49a9fc63a3 search 1 search query widg
2019-12-09 2019-12-09 12:57:35 5dea585477c94502b52c43fb f96305d9-590b-4a10-95a2-2d49a9fc63a3 search 1 search query wid
预期结果:
vacuum cleaner 1
blue widget 1
widget 1
4条答案
按热度按时间6qftjkof1#
一个看起来像倒着的圣诞树的日志文件;假设最后一个条目在最上面可能是安全的,因此,如果一个人能抓住每个组的第一条记录,那么你的问题就解决了,包括这个人拼错了什么然后改正的情况。这使得日期和时间与找到解决方案几乎无关。
假设您的字段“cid”表示一个搜索,这里有一个基于您的数据的解决方案,它精确地生成您的预期结果。输入数据应位于一个名为“inputable”的表中,创建为:
在不同的场景中运行下面的代码,以找到那些可能不起作用并且需要微调的特殊情况。
希望这能帮到你。
9nvpjoqh2#
不确定基于时间的方法是否最适合选择哪个值(例如2秒),用户在键入搜索词时可能会暂停更长时间。建议只查找本身不是同一会话中稍后键入的较长搜索词的子字符串的字符串。这种简单的方法可以通过标准sql实现:
例如,如果用户在删除“r”并正确键入“vacuum cleaner”之前错误地键入了“vacuum cleaner”,则查询将返回“vacuum cleaner”和“vacuum cleaner”。
请看这里的演示(用mysql编写,但clickhouse应该类似)。
ddarikpa3#
我假设用户不仅可以添加新字符,还可以删除字符,因此“xmas tree”规则不适用于每个最终查询。
此查询返回会话中最新的搜索输入(最终查询),可能不是会话中最长的搜索输入。
gz5pxeao4#
这个问题看起来很老。但不管怎样,我还是要和大家分享我的想法,这会帮助别人。
查看日志文件我看到的是它缺少一个强大的组键来选择每个客户的最新搜索。我从日志中注意到,每个客户的每次搜索都在1分钟内完成。考虑到这一事实,我要做的是在每个日志条目的timestamp列上创建一个新的dataset列(比如timestamp\ux),并将其格式化为“yyyy-mm-dd hh:mm”(因此秒被截断或放入00)。所以我有一个强大的分组键集(timestamp\ux和cid)。
之后,我将使用timestamp\ux和cid对数据集进行分组,并使用这些组键查询数据集,并在timestamp-through和order-by上取每个组的最新值。
在t-sql中,这可以通过with语句(公共表表达式)实现。不知道clickhouse里有什么相似之处。但是,我确信上述逻辑可以通过任何sql语言实现。
希望这有帮助!