복붙노트

[HADOOP] 돼지-지도 가방에서 반복하는 방법

HADOOP

돼지-지도 가방에서 반복하는 방법

문제를 설명하겠습니다. 이 코드 줄이 있습니다.

u = FOREACH persons GENERATE FLATTEN($0#'experiences') as j;
dump u;

이 출력을 생성합니다.

([id#1,date_begin#12 2012,description#blabla,date_end#04 2013],[id#2,date_begin#02 2011,description#blabla2,date_end#04 2013])
([id#1,date_begin#12 2011,description#blabla3,date_end#04 2012],[id#2,date_begin#02 2010,description#blabla4,date_end#04 2011])

그런 다음 내가 할 때 :

p = foreach u generate j#'id', j#'description';
dump p;

나는이 출력을 가지고있다 :

(1,blabla)
(1,blabla3)

그러나 그것은 내가 원하는 것이 아닙니다. 다음과 같은 출력을 원합니다.

(1,blabla)
(2,blabla2)
(1,blabla3)
(2,blabla4)

이걸 어떻게 가질 수 있습니까?

대단히 감사합니다.

해결법

  1. ==============================

    1.나는 당신이 u에서 FLATTENing하는 $ 0가 튜플이라고 가정합니다.

    나는 당신이 u에서 FLATTENing하는 $ 0가 튜플이라고 가정합니다.

    전반적인 문제는 j가 튜플의 첫 번째 맵만 참조한다는 것입니다. 원하는 출력을 얻으려면 각 튜플을 가방으로 변환 한 다음 FLATTEN해야합니다.

    각 튜플에 최대 2 개의 맵이 있다는 것을 알고 있다면 다음을 수행 할 수 있습니다.

    -- My B is your u
    B = FOREACH A GENERATE (tuple(map[],map[]))$0#'experiences' AS T ;
    B2 = FOREACH B GENERATE FLATTEN(TOBAG(T.$0, T.$1)) AS j ;
    
    C = foreach B2 generate j#'id', j#'description' ;
    

    튜플에 몇 개의 필드가 있는지 모르는 경우 훨씬 어려울 것입니다.

    참고 : 이것은 돼지 0.10에서 작동합니다.

    정의되지 않은 수의 맵이있는 튜플의 경우 가장 좋은 대답은 UDF를 사용하여 바이트 배열을 구문 분석하는 것입니다.

    myudf.py

    @outputSchema('vals: {(val:map[])}')
    def foo(the_input):
        # This converts the indeterminate number of maps into a bag.
        foo = [chr(i) for i in the_input]
        foo = ''.join(foo).strip('()')
        out = []
        for f in foo.split('],['):
            f = f.strip('[]')
            out.append(dict((k, v) for k, v in [ i.split('#') for i in f.split(',')]))
        return out
    

    myscript.pig

    register 'myudf.py' using jython as myudf ;
    B = FOREACH A GENERATE FLATTEN($0#'experiences') ;
    
    T1 = FOREACH B GENERATE FLATTEN(myudf.foo($0)) AS M ;
    T2 = FOREACH T1 GENERATE M#'id', M#'description' ;
    

    그러나 이것은 #,, 또는], [가 맵의 키 또는 값에 나타나지 않는다는 사실에 의존합니다.

    참고 : 이것은 돼지 0.11에서 작동합니다.

    따라서 돼지가 파이썬 UDF에 대한 입력을 처리하는 방법 이이 경우 변경 된 것으로 보입니다. 바이트 배열이 foo에 입력되는 대신 바이트 배열이 자동으로 적절한 유형으로 변환됩니다. 이 경우 모든 것이 훨씬 쉬워집니다.

    myudf.py

    @outputSchema('vals: {(val:map[])}')
    def foo(the_input):
        # This converts the indeterminate number of maps into a bag.
        out = []
        for map in the_input:
            out.append(map)
        return out
    

    myscript.pig

    register 'myudf.py' using jython as myudf ;
    
    # This time you should pass in the entire tuple.
    B = FOREACH A GENERATE $0#'experiences' ;
    
    T1 = FOREACH B GENERATE FLATTEN(myudf.foo($0)) AS M ;
    T2 = FOREACH T1 GENERATE M#'id', M#'description' ;
    
  2. from https://stackoverflow.com/questions/18180894/pig-how-to-iterate-on-a-bag-of-maps by cc-by-sa and MIT license