2013-12-19 1 views
2

JSON에 저장된 사용자 테이블을 나타내는 Firebase 데이터베이스의 덤프가 있습니다. 일부 데이터 분석을 실행하고 싶지만 메모리에 완전히로드하고 순수한 JavaScript (또는 _ 및 유사한 라이브러리)를 조작하기에는 너무 커서 문제가됩니다.JSON 객체를 다루기에 너무 커서 메모리에 맞을 수 없습니다.

지금까지 나는 JSONStream 패키지를 사용하여 바이트 크기의 청크로 데이터를 처리했습니다. JSON 덤프에서 각 사용자마다 한 번 콜백을 호출합니다.

나는 이제 필터 자신의 가치에 기반한 내 사용자 ID를 원하기 때문에로드 블록을 쳤습니다. 내가 대답하려고하는 "질문"은 "어떤 사용자 x"인지에 대한 질문입니다. 이전에 "얼마나 많은 사용자 x"를 물어 보았고 누구인지 알 필요가 없었습니다.

데이터 형식은 다음과 같이이다 :

{ 
    users: { 
     123: { 
      foo: 4 
     }, 
     567: { 
      foo: 8 
     } 
    } 
} 

내가하고 싶은 것은 본질적으로 foo의 값에 따라 사용자 ID (위의 123 또는 567)를 얻을 수있다. 자, 이것이 작은리스트라면 _.each과 같은 것을 사용하여 키와 값을 반복하고 원하는 키를 추출하는 것이 쉽습니다.

불행히도 메모리에 맞지 않아 작동하지 않습니다. JSONStream으로 나는 var parser = JSONStream.parse('users.*');를 사용하여 이런 식으로 다루는 함수로 배관하여 반복 할 수 있습니다

var stream = fs.createReadStream('my.json'); 

stream.pipe(parser); 

parser.on('data', function(user) { 
    // user is equal to { foo: bar } here 
    // so it is trivial to do my filter 
    // but I don't know which user ID owns the data 
}); 

그러나 문제는 내가 스타 와일드 카드를 나타내는 키에 액세스 할 수없는 것입니다 그 I JSONStream.parse로 전달되었습니다. 즉, { foo: bar}이 사용자 123 또는 사용자 567을 나타내는 지 여부는 알 수 없습니다.

질문은 두 가지이다 :

  1. 가 어떻게 내 콜백 내에서 현재 경로를 얻을 수 있나요?
  2. 메모리에 저장하기에는 너무 큰이 JSON 데이터를 처리하는 더 좋은 방법이 있습니까?
+0

1. 전혀 할 수 없습니다. 절대 일어나지 않을 것입니다 (현재 구조 사용). 왜이 JSON을 실제 데이터베이스 (예 : MySQL)에 넣고 실제로 쿼리하여 분석을 수행할까요? – Adam

+0

Can not what? 데이터보다 기술적으로 경로에 액세스 할 수있는 방법이 있습니까? –

+0

콜백에서 알아 낸대로'경로 '가 없으며 데이터 만 있습니다. 컨텍스트가없고 JSON 문자열의 "child"객체는 어디에서 왔는지 개념이 없습니다. – Adam

답변

4

이 기능을 추가하기 위해 JSONStream을 편집했습니다.

사람이 가로 지르는 유사를 패치하고 싶은 경우에, 당신은 이전에이와

stream.queue(this.value[this.key]) 

했다 line 83 대체 할 수있다 : 원래의 질문에서 코드 샘플에서

var ret = {}; 
ret[this.key] = this.value[this.key]; 

stream.queue(ret); 

, 오히려을 user은 콜백에서 { foo: bar }과 같습니다. 이제 { uid: { foo: bar } }

내가 원래 프로젝트로 다시 요청을 제출하지 않았지만, 미래에 플래그 또는 옵션을 추가하려는 경우 문제점에 남겨 두었습니다.

+2

마지막으로 키 이름 만 반환하는 대신 JSON 객체의 전체 경로가 포함 된 문자열을 반환 할 수 있도록 각 반복에서 현재 경로를 유지 관리하는 것도 한 가지 방법입니다. –

+0

그래, 그게 아마도 좋을 것 같아. Node의 Stream 클래스에 익숙하지 않아이 작업을 수행하는 방법을 알 수 있지만 이상적으로 콜백은 2 개의 매개 변수를 취합니다. 첫 번째는 데이터이고 두 번째는 경로 세그먼트의 배열입니다. 원본 JSON (예 : [사용자], [123 ']). 그렇게하면 현재의 깊이, 임의의 수의 와일드 카드 등을 쉽게 얻을 수 있습니다. –

+1

JSONStream은 스트림이므로 데이터 제안자는 하나의 매개 변수 만 관리해야합니다. 두. 이것을 우회하는 한가지 방법은'{value : {...}, path : ''}'객체를 반환하는 것이지만, 이것은 하위 호환을 깨뜨릴 것입니다. –