2014-06-17 7 views
1

배열의 마지막 요소를 밀어 :몽고 집계 선택하고 나는 다음과 같은 구조의 문서가

{ 
..., 
trials:[ {..., 
      ref:[{a:1,b:2},{a:2,b:2},...] 
     }, 
     {..., 
      ref:[{a:1,b:2}] 
     }, 
     ..., 
     ] 
} 

ref 적어도 1

만약의 길이 보장 배열입니다 I 각각의 ref 배열에있는 각 요소의 개별 항목을 계산하려면 다음 집계를 사용합니다.

db.cl.aggregate([ 
    {$unwind:"$trials"}, 
    {$unwind:"$trials.ref"}, 
    {$group:{_id:"$trials.ref", count:{$sum:1}}} 
]) 

가 지금은하지만 각 ref 배열의 마지막 요소, 같은 일을하고 싶어 (이 잘 작동). 집계 파이프 라인에서 각 배열의 마지막 요소 만 선택하는 방법이 필요합니다.

은 내가 먼저 내가 중간 단계가 바로이 같은 일을 수행하여 나는 그룹에 원하는 모든 요소를 ​​얻기 위해 추가 할 수 있다고 생각 : 나는 또한 $match에 위치 연산자를 사용하려고했습니다

db.cl.aggregate([ 
    {$unwind:"$trials"}, 
    {$group:{_id:null,arr:{$push:"$trials.ref.-1"}}},... 
]) 

.

db.cl.aggregate([ 
    {$unwind:"$trials"}, 
    {$match:{"trials.ref.$":-1}},... 
]) 

마지막 요소를 투영하려고합니다.

db.cl.aggregate([ 
    {$unwind:"$trials"}, 
    {$project:{ref:"$trials.ref.1"}} 
]) 

둘 중 어느 것도 나를 데려 오지 않습니다. $pop 연산자가 집계 파이프 라인에서 유효하지 않습니다. $last 연산자는 여기서는별로 유용하지 않습니다.

ref 배열의 마지막 요소 만 사용하는 방법에 대한 아이디어가 있습니까? 차라리 집계 프레임 워크를 유지하고 Map Reduce를 사용하지 않을 것입니다.

+0

당신이 생각하는 것보다 훨씬 어려운 질문입니다. [here] (http : // stackoverflow.com/q/21949521/2313887) –

+0

저는 이것이 흥미로운 질문이라는 것을 완전히 알고 있습니다. 나는 여기에 나의 시도 중 일부만 보여 주었다. 나는 이것에 대해 생각하면서 꽤 많은 시간을 보냈다. 모든'ref' 배열을 질의하고 계산을 로컬로 수행 할 수는 있지만, 그렇지 않을 수도 있습니다. –

+0

내가 직면하고있는 문제가 "상위 n"문제이기 때문에 다른 질문을 참조했습니다. 집계 프레임 워크에서는'$ slice '를 사용할 수 없습니다. 그리고 이것은 당신이하고 싶은 일에 주어진 문제입니다. 그림과 같이'$ first'와'$ match'의 레이어로 에뮬레이트 할 수 있습니다. 그러나 그룹화 당 배열의 "n"결과를 얻는 쉬운 방법은 없습니다. 이것은 기본적으로 당신이 요구하는 것입니다. –

답변

1

집계 프레임 워크에는이 문제를 처리 할 수있는 방법이 없습니다. "슬라이스"유형 연산자가 부족한 것 외에도 내부 배열이 끝나는 위치를 나타내는 마커가 없기 때문에 다른 형식의 문서 다시 형성을 수행 할 수있는 방법이 없습니다. 지금은

적어도, 맵리 듀스 접근 방식은 매우 간단합니다, 심지어 감속기가 필요하지 않습니다 희망이있을 수 있습니다

db.cl.mapReduce(
    function() { 
     this.trials.forEach(function(trial) { 
      trial.ref = trial.ref.slice(-1); 
     }); 

     var id = this._id; 
     delete this._id; 

     emit(id, this); 
    }, 
    function(){}, 
    { "out": { "inline": 1 } } 
) 

향후합니다. 어떤 형태의 $slice은 얼마 동안 찾았습니다. 그러나 나는이 재미있는 스 니펫을 $mapoperator code 안에 넣었다. 여기에 목록으로 표시하려면

output.reserve(input.size()); 
    for (size_t i=0; i < input.size(); i++) { 
     vars->setValue(_varId, input[i]); 

     Value toInsert = _each->evaluateInternal(vars); 
     if (toInsert.missing()) 
      toInsert = Value(BSONNULL); // can't insert missing values into array 

     output.push_back(toInsert); 
    } 

루프와 색인 값에 유의하십시오. 왜냐하면 당신이 효과적으로 "조각 내기"를 할 수있는 배열의 현재 위치와 길이를 알고있는 한 사람이 이것을 $map 연산자 내에서 변수로 드러내도록 투표 할 것이기 때문입니다.

그러나 지금은 $map을 사용하여 배열에있는 위치를 알 수있는 방법이 없으며 두 배열 모두 $unwind 인 경우 내부 배열의 끝점을 잃어 버리게됩니다. 따라서 집계 프레임 워크는 현재 솔루션에 부족합니다.

+0

응용 프로그램 측면에서이 작업을 수행했습니다. 각 시험판에서 전체 배열을 가져옵니다. –

관련 문제