我正在基于名称和位置字段实现从公司规范化数据库中提取的JSON对象与来自Twitter的非结构化数据之间的连接。为了澄清,这个连接是使用MapReduce完成的,因此没有其他方法可以手动实现连接条件。 显而易见的实现是将这些字段与Java String.equals方法进行连接和比较。考虑这两个JSON,第一个从规范化数据中提取,第二个来自Twitter:
{"location":"Rio de Janeiro - Brasil","name":"Joao Paulo Forny "}
{"location":"RiodeJaneiro;Brasil","name":"JoaoPaulo-Forny!"}
下面的连接条件可以找到相同名称和位置之间的匹配,这些匹配包含相同顺序的相同字母,因为使用正则表达式来消除所有空格和其他字符而不是字母。
obj1.getJoinKey().toLowerCase().replaceAll("[^A-Za-z]", "")
.equals(ob2.getJoinKey().toLowerCase().replaceAll("[^A-Za-z]", ""))
由于Twitter数据未规范化,因此字段不能包含任何信息或仅包含信息,甚至不包含与特定字段无关的信息,因此有些情况无法计算任何内容。但是,有些情况可能会找到可能的匹配,例如,位置可能只包含城市,名称可能没有所有的中间名或姓氏,也可能是相同但不按顺序的单词。
{"location":"Rio de Janeiro - Brasil","name":"Joao Paulo Forny de Melo"}
{"location":"Rio de Janeiro","name":"Joao Paulo Forny de Melo"}
{"location":"Rio de Janeiro - Brasil","name":"Joao Paulo Forny de Melo"}
{"location":"Rio de Janeiro - Brasil","name":"Joao Forny"}
{"location":"Rio de Janeiro - Brasil","name":"Joao Paulo Forny de Melo"}
{"location":"Brasil - Rio de Janeiro","name":"Joao Paulo Forny de Melo"}
问题是,根据上述三个条件,可以使用哪些解决方案来找到潜在的匹配?
答案 0 :(得分:1)
通过您提供的三个具体示例:
一个位置仅包含城市;另一个包含城市和州/国家。在这种情况下,您可以将字符串分成两部分,由任何非字母数字,非空白字符分隔,并规范化间距(可能通过删除它)。例如,“Brasil; Rio de Janiero”将成为“Brasil”和“RiodeJaniero”。然后,您可以测试其中一个位置中的至少一个子字符串是否与其他位置之一的子字符串匹配。为了防止仅匹配国家/地区,您可以设想创建所有国家/地区的列表并排除这些匹配项。只有几百个国家,虽然我肯定根据语言有许多替代拼写。但如果你不这样做,你最终会匹配,比如“圣保罗 - 巴西”和“里约热内卢 - 巴西”。
一个名字可能没有中间名或姓氏。我倾向于认为你必须至少拥有名字和姓氏才能匹配。想象一下巴西或葡萄牙有多少Joaos。因此,在这种情况下,将字符串分解为子字符串,并确保至少两个部分相互匹配。不过,您需要另外一个排除列表,其中包括“von”,“de”和“O”等内容。
州和国家的顺序相反。这只是上面#1的一个特例。你将有两个子串匹配而不只是一个。
希望这会有所帮助。我不确定这是一个完整的解决方案,但希望至少它可以引导您前往完整的解决方案。