2014-09-04 3 views
0

하위 문서가있는 스키마가 있습니다.Mongo 집합과 일치하는 하위 문서 만 반환

// Schema 
var company = { 
    _id: ObjectId, 
    publish: Boolean, 
    divisions: { 
    employees: [ObjectId] 
    } 
}; 

내 쿼리와 일치하는 모든 하위 문서 (부서)를 찾아야합니다. 2 개의 일치 항목을 사용해야하는 것으로 보입니다. 하나는 초기 문서를 필터링하고 두 번째 항목은 결과 $ unwind 작업에서 일치하는 하위 문서를 필터링합니다. 더 효율적인 방법이 있습니까?

// Query 
this.aggregate({ 
    $match: { 
    'publish': 1, 
    'divisions.employees': new ObjectId(userid) 
    } 
    }, { 
    $unwind: '$divisions' 
    }, { 
    $match: { 
     'divisions.employees': new ObjectId(userid) 
    } 
    } 

나는 이걸 찾았지만, 내가 필요로하는 것이 확실하지 않다.

답변

0

두 가지 모두 일치하는 것이 올바른 것입니다. 첫 번째 일치 스테이지를 없애고 풀 수 있지만 초기 $ 일치를 사용하면 적어도 하나의 출력 문서 (즉, publish : true 및 일부 employees ObjectId가 지정된 문서와 일치하는 문서)를 파이프 라인으로 정확하게 축소 할 수 있습니다. ObjectId). { publish : 1, divisions.employees : 1 }의 색인과 같은 색인을 사용하여 첫 번째 일치 단계를 빨리 수행 할 수 있습니다.

그러나 여기에 집계 파이프 라인을 사용하는 이유와 적절한지 물어보십시오. publish : 1 인 회사에 속한 특정 직원을 쿼리하는 것이 일반적입니까? 유스 케이스의 주요 쿼리 중 하나입니까? 빈번하지 않거나 중요하지 않은 경우 집계를 수행하는 것이 좋습니다. 그렇지 않으면 스키마를 다시 고려해야합니다. 당신은 문서로

{ 
    "_id" : ObjectId, 
    "publish" : Boolean, 
    "company" : (unique identifier, possibly a String or ObjectId) 
} 

모델 직원과 같은 스키마이 쿼리를 쉽게하고 직원 문서에 회사 정보를 denormalizes 수 있습니다. (안 그 집계보다 훨씬 빨리 될 것

({사실 : "게시"ObjectId가 (사용자 ID) "_id"}) 그런 다음 쿼리는 쉽게

로 db.employees.find입니다 집계가 느려지는 것, 이것은 상대적으로 빠름). 이 방법으로 그렇게하지 말라고 말하는 것이 아닙니다. 유스 케이스에 대한 지식을 적절히 사용하여 올바른 전화를 걸 수 있습니다.

+0

감사합니다. 실제 코드가 상당히 복잡하기 때문에 집계가 필요하지 않습니다. 그래서 가장 효율적인 방법은 두 개의 match에서'division.employee' 쿼리를 유지하고 인덱스를 추가하는 것입니다. 두 번이나 두 번째에 division.employee를 넣어야하는지 잘 모르겠습니다. – cyberwombat

+0

둘 다 최고라고 생각합니다. 첫 번째 $ 경기는 색인을 사용하고 가능한 한 적은 수의 문서로 다음 단계를 처리하는 반면, 두 번째 $ 일치에서 올바른 결과를 얻으려면 조건이 필요합니다. – wdberkeley