2013-12-22 4 views
2

하위 문서 특성 값을 기반으로하는 Mongo 쿼리에 대한 도움이 필요하지만 해당 하위 문서 특성이 결과에 표시되지 않도록해야합니다.MongoDB 하위 문서 프로젝션

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    }, 
    { 
     "address" : "[email protected]", 
     "default" : false 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : false 
    }, 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
} 

내 목표는 다음과 같은 출력을 얻을 수 있습니다 : 여기

내 사용자 객체 ("emails.default"로 : 사실하지만 결과에 나타나는 "emails.default"속성없이) :

collection.find({"emails.default":true}, {"username":1,"emails.$":1}) 

내가 AP에 올바른 이메일 하위 문서를 얻을 다음 $ 위치 연산자를 사용
{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    } 
    ] 
} 

배,하지만 난 여전히 "emails.default"를 얻을 다시 속성 :

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
} 

을 어떤 이유로, 나는이 문장을 사용할 때 : 쿼리 것처럼 (나는 다음과 같은 결과를 얻을

collection.find({"emails.default":true}, {"username":1,"emails.address":1}) 

을 진술의 일부가 무시되었습니다)

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    }, 
    { 
     "address" : "[email protected]", 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    }, 
    { 
     "address" : "[email protected]", 
    } 
    ] 
} 

도움을 주신 데 대해 감사드립니다.

답변

1

나는 이것이 지원되는 기능이라고 생각하지 않습니다. 배열의 문서 안에 선택된 필드의 투영을 요구하고 있습니다. 이봐 ticket

하지만 당신의 문서 구조가 많은 중복 데이터를 저장할 것 같아요. 하나의 기본 전자 메일 주소 만있을 것입니다. 이것을 부모 문서의 일부로 만듭니다. 업데이트/프로젝션이 훨씬 더 간단 해집니다. 귀하의 배열 emails은 실제로 이메일 만 저장합니다.

3

위치 연산자 (MongoDB 2.6에서와 같이)를 사용하면 일치하는 배열 요소의 필드를 선택적으로 제외 할 수 없습니다.

db.user.aggregate(

    // Match on relevant documents to optimize query 
    { $match: { 
     username: "abc" 
    }}, 

    // Convert the "emails" address into a stream of documents 
    { $unwind: "$emails" }, 

    // Only include the emails with default:true 
    { $match: { 
     "emails.default" : true 
    }}, 

    // Project the desired fields 
    { $project: { 
     _id : 0, 
     username: 1, 
     "emails.address": 1 
    }} 
) 

샘플 결과 :

{ 
    "username" : "abc", 
    "emails" : { 
     "address" : "[email protected]" 
    } 
} 

그러나, 당신은 원하는 결과를 달성하기 위해 MongoDB를 2.2으로 집계 프레임 워크를 사용할 수 있습니다