2012-11-08 4 views
1

나는 많은 문서 (아마 수백만 개)를 가진 콜렉션을 가지고있다. 사용자가 새 문서를 삽입하면 인덱싱 할 수있는 데이터의 "순서"를 유지하는 필드가 필요합니다. 예를 들어, 한 필드가 시간 인 경우 "1352392957.46516"형식으로, 세 개의 문서가있는 경우 첫 번째 시간은 1352392957.46516이고 두 번째 시간은 1352392957.48516 (20ms)이고 세 번째 문서는 1352392957.49516 (10ms 후)입니다. 첫 번째 문서가 0이고 두 번째 문서가 1, 세 번째 문서가 두 번째 필드가되는 다른 필드를 갖기를 원합니다.mongodb 콜렉션의 순서 유지

내가 원하는 이유는 해당 필드를 인덱싱 할 수 있기 때문에 데이터를 샘플링하기 위해 효율적인 $ mod 연산을 찾을 수 있습니다. 예를 들어, 만약 내가 백만 개의 문서를 가지고 있고 그 중 1000 개만 고르게 배치하고자한다면 정수 필드에 $ mod [1000, 0]을 할 수 있습니다.

시간 필드에서 할 수없는 이유는 완벽하게 간격을 두지 않았거나 모두 짝수이거나 홀수 일 수있어서 모드가 작동하지 않기 때문입니다. 따라서 별도의 정수 필드는 선형으로 증가하는 순서로 순서를 유지합니다.

또한 컬렉션의 모든 위치에 문서를 삽입 할 수 있어야하므로 모든 후속 필드를 업데이트해야합니다.

자동으로이 작업을 수행 할 수있는 방법이 있습니까? 아니면 이것을 구현해야합니까? 또는 내가 설명하는 것을 수행하는보다 효율적인 방법이 있습니까?

+1

이 HTTP : // WWW .mongodb.org/display/DOCS/How + to + + + Auto + Incrementing + Field는 질문에 거의 답을해야합니다. –

+0

왜 문서를 "삽입"해야합니까? "모든 후속 정수"를 업데이트하는 것은 고통 스럽습니다. 끝까지 추가 할 수없는 이유가 있습니까? 정수도 정렬 순서로되어 있습니까? – cirrus

+0

정수는 데이터를 효율적으로 샘플 다운 할 수있는 유일한 방법이므로 정렬 순서 여야합니다. 사용자가 이전보다 타임 스탬프가 오래된 데이터를 삽입 할 수 있기를 바랍니다. –

답변

1

단일 삽입에 대해 수백만 개의 문서를 업데이트하는 경우 "느린 삽입"을 훨씬 능가합니다.이 방법은 전체 수집을 활성 작업 집합으로 만듭니다. 마찬가지로 키 값과 $mod 비교를 수행하려면 색인의 모든 키 값을 비교해야합니다.

정렬 된 샘플링 순서에 대한 요구 사항을 감안할 때 더 효율적인 preaggregation 접근 방법이 있는지 확신 할 수 없습니다.

랜덤 문서를 가져 오는 데 skip() and limit()을 사용합니다. skip() 명령은 원하지 않는 문서를 통해 각각의 시간을 건너 뛸 인덱스의 처음부터 스캔 될 것입니다,하지만 당신은 메모리에 인덱스를 유지하기에 충분한 RAM이있는 경우 성능은 허용해야한다 :

// Add an index on time field 
db.data.ensureIndex({'time':1}) 

// Count number of documents 
var dc = db.data.count() 

// Iterate and sample every 1000 docs 
var i = 0; var sampleSize = 1000; var results = []; 
while (i < dc) { 
    results.push(db.data.find().sort({time:1}).skip(i).limit(1)[0]); 
    i += sampleSize; 
} 

// Result array of sampled docs 
printjson(results); 
+0

나를 위해 어쨌든 쿼리 결과를 캐싱 할 계획이었습니다. 이 예제에서는 1000 개 이상의 항목이 추가 된 경우에만이 유형의 쿼리를 다시 실행하면됩니다. –

+0

맵 축소를 사용하여 종료되었습니다. 위의 대답은 너무 느린 것으로 판명되었습니다. 이제 mapReduce에 스코프 옵션을 사용하고 외부 수와 색인을 유지합니다. 정렬을 사용하여 입력을 정렬하고 원하는 문서 배열로 결과 문서를 작성합니다. 이것은 정말 빠른 것 같습니다. –