【问题标题】:HIVE/PIG JOIN Based on SUBSTRING matchHIVE/PIG JOIN 基于 SUBSTRING 匹配
【发布时间】:2021-12-28 18:31:30
【问题描述】:

我有一个要求,我需要加入一个包含人名的推文表,例如过滤包含任何人名的推文。我有以下数据:

推文表:(7000 万条记录存储为 HIVE 表)

id tweet
1 Cristiano Ronaldo greatest of all time
2 Brad Pitt movies
3 Random tweet without any person name

人物姓名:(160 万个姓名以 .tsv 文件形式存储在 HDFS 上)

id person_name
1 Cristiano Ronaldo
2 Brad Pitt
3 Angelina Jolie

预期结果:

id tweet person_name
1 Cristiano Ronaldo greatest of all time Cristiano Ronaldo
2 Brad Pitt movies Brad Pitt

到目前为止我已经尝试过:

我也将人名 .tsv 文件转换为 HIVE 表,然后尝试使用以下 HIVE 查询连接 2 个表:

SELECT * FROM tweets t INNER JOIN people p WHERE instr(t.tweet, p.person_name) > 0;

尝试了一些示例数据,它工作正常。但是当我尝试运行整个数据时(7000 万条推文与 160 万个人姓名一起加入),它需要很长时间。绝对看起来效率不高。

我也想尝试使用 PIG 进行 JOIN(因为它被认为比 HIVE JOIN 更有效),我可以直接加入人名 .tsv 文件 tweets HIVE 表,但不确定如何基于 PIG 中的子字符串加入.

如果你有任何想法,有人可以分享这个问题的 PIG JOIN 语法吗?另外,请给我建议我可以使用的任何替代方案吗?

【问题讨论】:

  • I wanted to try JOIN with PIG as well (as it is considered little more efficient than HIVE JOIN), 这几天几乎肯定不是真的; Pig 已经 4 年没有发布了,而 Hive 仍在积极开发中。
  • 谢谢。没错,但我很想尝试 PIG 脚本。你知道这种 JOIN 的语法在 PIG 中是什么样的吗?

标签: hadoop join hive bigdata apache-pig


【解决方案1】:

值得一试 Map-Join。 Person 表很小,如果它适合内存,可以将其连接到 Map-Join 运算符。表将被加载到每个映射器内存中。

检查 EXPLAIN 输出。如果它说Common Join operator 在 Reducer 顶点上,则尝试增加映射器容器内存并调整 map-join 设置以转换为 Map Join。

负责 Map Join 的设置(假设 People 表

 set hive.auto.convert.join=true; --this enables map-join
 set hive.auto.convert.join.noconditionaltask = true;
 set hive.mapjoin.smalltable.filesize=2500000000; --size of table to fit in memory
 set hive.auto.convert.join.noconditionaltask.size=2500000000;

还应增加容器大小以避免 OOM(如果您在 Tez 上):

set hive.tez.container.size=8192;  --container size in megabytes
set hive.tez.java.opts=-Xmx6144m;  --set this 80% of hive.tez.container.size

数字只是一个例子。尝试调整并再次检查 EXPLAIN,如果显示 Map-Join 运算符,则再次检查执行,它应该运行得更快。

【讨论】:

  • 我认为这是一个可靠的答案,如果它适合记忆的话。
【解决方案2】:

这个想法是创建存储桶,这样我们就不必比较很多记录。我们将增加记录/连接的数量以使用多个节点来完成工作,而不是使用大型交叉连接。--> WHERE instr(t.tweet, p.person_name) > 0;

  1. 我建议将推文拆分为单个单词。是的,让您的记录数成倍增加。
  2. 过滤掉“停用词”或其他适合记忆的单词列表。
  3. 将姓名分为(名)和“姓”
  4. 在“姓氏”和instr(t.tweet, p.person_name) 上加入推文和姓名,这应该会显着减少您通过函数比较的数据大小。它会运行得更快。

如果您要定期执行此操作,请考虑使用 sort/bucket 真正让事情变得咝咝作响。 (让它更快,因为它有望为 Sort Merge Join 做好准备。)

【讨论】:

  • 您能否提供更多详细信息,这一步的结果应该是什么:“将推文拆分为单个单词”例如,推文 1 将变为 6,停用词可能类似于“of, all, time “也许最棒的还有过滤会产生两排克里斯蒂亚诺和罗纳尔多?对吗?
  • 读过没有那么多姓氏。例如,中国总共有大约 6000 个姓氏。嗯……分裂是有道理的。 +
  • 例如 tweet 1 将变为 6 --> 是的。停用词-> 是公认的词,并没有真正增加意义。这将是一个好的开始,但可以添加更多内容。 (可能是不会用作名称的单词的良好来源。)过滤将产生两行克里斯蒂亚诺和罗纳尔多? --> 不只是 1 行,如果你愿意,真的可以使用名字,你只是想确保这条推文“可以”匹配。 (所以任何一个名字都可以。)欧美文化通常重用名字的频率高于姓氏。
  • @MattAndruff 听起来不错。但是在这里获得名人的姓氏本身就很棘手。没有完美的方法来提取它。所以,我只是在想,不是按单个单词拆分推文并根据名人的姓氏加入,HIVE 中有没有办法将推文分成二元组和三元组(因为全名通常可以是 2 -3个字),这样我就可以直接加入名人全名列表?例如,对于一条推文“克里斯蒂亚诺·罗纳尔多时代”,n-gram 将是“克里斯蒂亚诺·罗纳尔多”、“罗纳尔多时代”、“克里斯蒂亚诺·罗纳尔多时代”。
  • 您不必担心使用姓氏。使用名字。随机选择名称的任何部分。那不是重点。关键是您正在减少潜在候选人的数量。 (不再是对潜在匹配的全表扫描)。您正在使用连接来减少与至少有一定匹配机会的潜在目标的比较。
猜你喜欢
  • 1970-01-01
  • 2017-08-19
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多