2013-12-12 3 views
0

개체 배열을 포함하는 개체를 반환하는 쿼리가 있습니다. 객체의 배열 내에 처리되지 않아야하는 일부가 있습니다. 여기 개체에 simmilar 내가 무엇을하는 것입니다 :

{ 
    _id: 12345, 
    data: [ 
     { 
      state: 1, 
      info: "abc" 
     },{ 
      state: 2, 
      info: "cde" 
     },{ 
      state: 2, 
      info: "efg" 
     } 
    ] 
} 

것은 내가 상태1 동일하지 않는 개체 만 표시 할. 그래서 저는 다음과 같은 것을 되돌리고 싶습니다 :

{ 
    _id: 12345, 
    data: [ 
     { 
      state: 2, 
      info: "cde" 
     },{ 
      state: 2, 
      info: "efg" 
     } 
    ] 
} 

수십 개의 "하위"개체가있는 수 백 개의 "주요"개체가있을 수 있습니다. 내가 쿼리 사용하여 시도 :

col.find({'data.info': {$in: [] }, {_id: 1, data: { $elemMatch: { state: {$ne: 1 } } } }, {}, callback); 

을하지만 그건 나만이 제공 : 즉

{ 
    _id: 12345, 
    data: [ 
     { 
      state: 2, 
      info: "cde" 
     } 
    ] 
} 

를, $ elemMatch 어떻게해야 무엇 않습니다,하지만 난 다른 결과를 얻을 필요가있다. 그렇다면 하나의 쿼리에서 또는 미리 처리하지 않고 (추가 코드가 데이터를 읽기 전에 항목을 제거하지 않고) 수행 할 수있는 방법이 있습니까?

답변

1

$elemMatch projection operator은 배열에서 첫 번째로 일치하는 요소 만 반환합니다.

전체 배열을 필터링하려면 MongoDB 2.2 이상에서 가장 좋은 방법은 집계 프레임 워크를 사용하는 것입니다. 또는 Map/Reduce 또는 응용 프로그램 코드를 사용하여이 작업을 수행 할 수도 있습니다.

예 응집 :

db.data.aggregate(

    // Initial match to limit number of documents 
    { $match : { 
     data: { $elemMatch: { state: {$ne: 1 } } } 
    }}, 

    // Convert the data array into a stream of documents 
    { $unwind: "$data" }, 

    // Limit to matching elements of the data array 
    { $match : { 
     "data.state": {$ne: 1 } 
    }}, 

    // Re-group by original document _id 
    { $group: { 
     _id: "$_id", 
     data: { $push: "$data" } 
    }} 
) 

샘플 출력 :

{ 
    "_id" : 12345, 
    "data" : [ 
     { 
      "state" : 2, 
      "info" : "cde" 
     }, 
     { 
      "state" : 2, 
      "info" : "efg" 
     } 
    ] 
} 
관련 문제