我正在尝试使用字符串模板来生成Pig / Hadoop代码。由于我是新手,我自己也无法弄清楚。任何帮助将不胜感激。
我有一个LocalDate列表,如下面的一个节目
List<LocalDate> dates = Arrays.asList("20100101", "20100102").stream().map(d -> LocalDate.parse(d,formatter)).collect(Collectors.toList());
该列表可以包含1个日期或许多日期。
如果列表&#34;日期&#34;包含多个元素,然后我想生成:
SPLIT finalizedEvents INTO splitByDay_20100101 IF dataDate == 20100101,
INTO splitByDay_20100102 IF dataDate == 20100102, ....; // for all date in "dates" list
// similarly for all dates
// formatting substitution variable e.g. 2010/01/01 instead of 20100101 is needed
STORE splitByDay_20100101 INTO '/a/b/2010/01/01' USING AvroStorage();
STORE splitByDay_20100102 INTO '/a/b/2010/01/02' USING AvroStorage();
如果列表&#34;日期&#34;只包含一个元素然后我想生成(假设日期= [20100101])
splitByDay_20100101 = FOREACH finalizedEvents GENERATE $0..;
STORE splitByDay_20100101 INTO '/a/b/2010/01/01' USING AvroStorage();
到目前为止,我已经做了类似以下的事情但不确定如何进行条件
ST e = new ST("SPLIT finalizedEvents INTO <[dates]:{ d | IF split_<d> BY daysSinceEpoch == <d>}; separator=\", \">;");
e.add("dates", dates);
System.out.println(e.render());
答案 0 :(得分:0)
以下是我提出的问题(详细说明如下):
List<LocalDate> dates = new ArrayList<>();
dates.add(LocalDate.parse("20100101", DateTimeFormatter.BASIC_ISO_DATE));
dates.add(LocalDate.parse("20100201", DateTimeFormatter.BASIC_ISO_DATE));
List<List<Character>> charListList = new ArrayList<>();
for (LocalDate date : dates) {
List<Character> charList = new ArrayList<>();
char[] dateCharArray = date.toString().toCharArray();
for (char c : dateCharArray) {
charList.add(c);
}
charListList.add(charList);
}
STGroup dateGroup = new STGroupFile("./src/com/stackoverflow/DateList/dates.stg");
ST dateTemp = dateGroup.getInstanceOf("writeCode");
dateTemp.add("formattedDates", charListList);
dateTemp.add("isSingle", charListList.size() == 1);
System.out.println(dateTemp.render());
writeCode(formattedDates, isSingle) ::= <<
<if(isSingle)><writeSingleStuff(formattedDates)>
<else><writeMultipleStuff(formattedDates)>
<endif>
<writeStoreList(formattedDates)>
>>
writeSingleStuff(date)::= "<date:{d|splitByDay_<wordReplaceWSlash(d)> = FOREACH finalizedEvents GENERATE $0..;}>"
writeMultipleStuff(rawDates)::= "SPLIT finalizedEvents <rawDates:{d|INTO splitByDay_<wordReplaceWEmpty(d)> IF dataDate == <wordReplaceWEmpty(d)>}; separator=\", \">;"
writeStoreList(formattedDates)::= "<formattedDates:{d|STORE splitByDay_<wordReplaceWEmpty(d)> INTO '/a/b/<wordReplaceWSlash(d)>' USING AvroStorage();<\n>}>"
wordReplaceWSlash(word) ::= "<word:{char|<charReplaceWSlash(char)>}>"
charReplaceWSlash(theChar) ::= <%<charReplaceWSlashMap.(theChar)>%>
charReplaceWSlashMap ::= [
"-":"/",
default:{<theChar>}
]
wordReplaceWEmpty(word) ::= "<word:{char|<charReplaceWEmpty(char)>}>"
charReplaceWEmpty(theChar) ::= <%<charReplaceWEmptyMap.(theChar)>%>
charReplaceWEmptyMap ::= [
"-":"",
default:{<theChar>}
]
List<LocalDate> dates = new ArrayList<>();
dates.add(LocalDate.parse("20100101", DateTimeFormatter.BASIC_ISO_DATE));
dates.add(LocalDate.parse("20100201", DateTimeFormatter.BASIC_ISO_DATE));
这是一个包含LocalDates
的列表,我们希望将其用作模板的输入。我用DateTimeFormatter.BASIC_ISO_DATE
对它们进行了格式化,例如20100101
变为2010-01-01
。我们稍后需要这个,因为我们将告诉StringTemplate将-
替换为/
或空字符串以获取我们想要的两种类型的日期格式(我没有找到获取{的格式化程序{1}}首先)
两种不同的方法是:
2010/01/01
替换为-
,而不是在StringTemplate中。然后,如果我们需要这种日期格式,我们只需要用空字符串替换/
。/
。
/
我们不得不这样做,但是:
我们必须有一个日期字符的列表(和不是数组),以便我们可以在StringTemplate中“迭代”它。还有no direct way将char []转换为List。最后,我们必须将所有这些列表放在一个列表中,以便我们可以为每个日期生成代码(List<List<Character>> charListList = new ArrayList<>();
for (LocalDate date : dates) {
List<Character> charList = new ArrayList<>();
char[] dateCharArray = date.toString().toCharArray();
for (char c : dateCharArray) {
charList.add(c);
}
charListList.add(charList);
}
)。
charListList
这里我们用值填充模板。我们必须告诉StringTemplate here 我们的STGroup dateGroup = new STGroupFile("./src/com/stackoverflow/DateList/dates.stg");
ST dateTemp = dateGroup.getInstanceOf("writeCode");
dateTemp.add("formattedDates", charListList);
dateTemp.add("isSingle", charListList.size() == 1);
System.out.println(dateTemp.render());
中是否只有一个日期,因为StringTemplate是(by design)无法这样做。
charListList
这是“根”模板,基本上只是将工作委托给其他模板。它处理一个或多个日期之间的案件干扰。
writeCode(formattedDates, isSingle) ::= <<
<if(isSingle)><writeSingleStuff(formattedDates)>
<else><writeMultipleStuff(formattedDates)>
<endif>
<writeStoreList(formattedDates)>
>>
通过这三行,我们编写了特定于单个项目的代码,多个项目以及两者具有共同点的代码。
虽然我们知道writeSingleStuff(date)::= "<date:{d|splitByDay_<wordReplaceWSlash(d)> = FOREACH finalizedEvents GENERATE $0..;}>"
writeMultipleStuff(rawDates)::= "SPLIT finalizedEvents <rawDates:{d|INTO splitByDay_<wordReplaceWEmpty(d)> IF dataDate == <wordReplaceWEmpty(d)>}; separator=\", \">;"
writeStoreList(dates)::= "<dates:{d|STORE splitByDay_<wordReplaceWEmpty(d)> INTO '/a/b/<wordReplaceWSlash(d)>' USING AvroStorage();<\n>}>"
在我们输入date
时只有一个项目,但我们必须遍历列表。
writeSingleStuff
这两组模板几乎完全相同:用wordReplaceWSlash(word) ::= "<word:{char|<charReplaceWSlash(char)>}>"
charReplaceWSlash(theChar) ::= <%<charReplaceWSlashMap.(theChar)>%>
charReplaceWSlashMap ::= [
"-":"/",
default:{<theChar>}
]
wordReplaceWEmpty(word) ::= "<word:{char|<charReplaceWEmpty(char)>}>"
charReplaceWEmpty(theChar) ::= <%<charReplaceWEmptyMap.(theChar)>%>
charReplaceWEmptyMap ::= [
"-":"",
default:{<theChar>}
]
或空字符串替换每个“单词”中的每个-
个字符。我们使用一个小字典来替换除/
之外的所有字符。