복붙노트

[MONGODB] MongoDB의 컬렉션에서 객체 배열 만 조회 된 값을 가져옵니다

MONGODB

MongoDB의 컬렉션에서 객체 배열 만 조회 된 값을 가져옵니다

당신이 내 컬렉션에 다음과 같은 문서가 있다고 가정 :

{  
   "_id":ObjectId("562e7c594c12942f08fe4192"),
   "shapes":[  
      {  
         "shape":"square",
         "color":"blue"
      },
      {  
         "shape":"circle",
         "color":"red"
      }
   ]
},
{  
   "_id":ObjectId("562e7c594c12942f08fe4193"),
   "shapes":[  
      {  
         "shape":"square",
         "color":"black"
      },
      {  
         "shape":"circle",
         "color":"green"
      }
   ]
}

쿼리 수행

db.test.find({"shapes.color": "red"}, {"shapes.color": 1})

또는

db.test.find({shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color": 1})

반환 일치하는 문서 (문서 1), 그러나 항상 모양의 모든 배열 항목 :

{ "shapes": 
  [
    {"shape": "square", "color": "blue"},
    {"shape": "circle", "color": "red"}
  ] 
}

그러나, 나는 단지 색깔이 빨간색 =이 들어있는 배열 문서 (문서 1) 좀하고 싶습니다 :

{ "shapes": 
  [
    {"shape": "circle", "color": "red"}
  ] 
}

이걸 어떻게 할 수 있습니까?

해결법

  1. ==============================

    1.MongoDB를 2.2의 새로운 $ elemMatch 프로젝션 연산자는 첫 번째 일치하는 도형 요소를 포함하는 반환 된 문서를 변경하는 또 다른 방법을 제공합니다 :

    MongoDB를 2.2의 새로운 $ elemMatch 프로젝션 연산자는 첫 번째 일치하는 도형 요소를 포함하는 반환 된 문서를 변경하는 또 다른 방법을 제공합니다 :

    db.test.find(
        {"shapes.color": "red"}, 
        {_id: 0, shapes: {$elemMatch: {color: "red"}}});
    

    보고:

    {"shapes" : [{"shape": "circle", "color": "red"}]}
    

    2.2은 또한 투영 대물 필드 이름에 $가 쿼리 필드의 첫 번째 일치 배열 요소의 인덱스를 나타내는 $ 투영 오퍼레이터를 사용하여이를 수행 할 수있다. 다음 반환 상기와 같은 결과 :

    db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});
    

    MongoDB를 3.2 업데이트

    3.2 릴리스부터 대신 첫 번째로, 모든 일치 등의 이점이 투사하는 동안 배열을 필터링하는 새로운 $ 필터 집계 연산자를 사용할 수 있습니다.

    db.test.aggregate([
        // Get just the docs that contain a shapes element where color is 'red'
        {$match: {'shapes.color': 'red'}},
        {$project: {
            shapes: {$filter: {
                input: '$shapes',
                as: 'shape',
                cond: {$eq: ['$$shape.color', 'red']}
            }},
            _id: 0
        }}
    ])
    

    결과 :

    [ 
        {
            "shapes" : [ 
                {
                    "shape" : "circle",
                    "color" : "red"
                }
            ]
        }
    ]
    
  2. ==============================

    2.MongoDB의 2.2의 새로운 집계 프레임 워크지도에 대한 대안을 제공합니다 / 줄입니다. 은 $ 언 와인드 연산자는 일치 할 수있는 문서의 스트림으로 모양의 배열을 분리 할 수 ​​있습니다 :

    MongoDB의 2.2의 새로운 집계 프레임 워크지도에 대한 대안을 제공합니다 / 줄입니다. 은 $ 언 와인드 연산자는 일치 할 수있는 문서의 스트림으로 모양의 배열을 분리 할 수 ​​있습니다 :

    db.test.aggregate(
      // Start with a $match pipeline which can take advantage of an index and limit documents processed
      { $match : {
         "shapes.color": "red"
      }},
      { $unwind : "$shapes" },
      { $match : {
         "shapes.color": "red"
      }}
    )
    

    결과 :

    {
        "result" : [
            {
                "_id" : ObjectId("504425059b7c9fa7ec92beec"),
                "shapes" : {
                    "shape" : "circle",
                    "color" : "red"
                }
            }
        ],
        "ok" : 1
    }
    
  3. ==============================

    3.필드 선택 매개 변수는 완전한 속성으로 제한됩니다. 배열 만 전체 어레이의 일부를 선택하기 위해 사용될 수 없다. 나는 $ 위치 연산자를 사용하여 시도하지만, 작동하지 않았다.

    필드 선택 매개 변수는 완전한 속성으로 제한됩니다. 배열 만 전체 어레이의 일부를 선택하기 위해 사용될 수 없다. 나는 $ 위치 연산자를 사용하여 시도하지만, 작동하지 않았다.

    가장 쉬운 방법은 클라이언트의 모양을 필터링하는 것입니다.

    당신이 정말로 MongoDB를에서 직접 올바른 출력을해야하는 경우, 당신이 사용할 수있는 형태를 필터링 할지도 - 줄일 수 있습니다.

    function map() {
      filteredShapes = [];
    
      this.shapes.forEach(function (s) {
        if (s.color === "red") {
          filteredShapes.push(s);
        }
      });
    
      emit(this._id, { shapes: filteredShapes });
    }
    
    function reduce(key, values) {
      return values[0];
    }
    
    res = db.test.mapReduce(map, reduce, { query: { "shapes.color": "red" } })
    
    db[res.result].find()
    
  4. ==============================

    4.또 다른 interesing 방법은 MongoDB를 2.6의 새로운 통합 기능 중 하나입니다 $ 편집하다을 사용하는 것입니다. 당신은 2.6를 사용하는 경우, 당신은 당신이 큰 배열이있는 경우 당신에게 성능 문제가 발생할 수 있습니다 $ 언 와인드 필요하지 않습니다.

    또 다른 interesing 방법은 MongoDB를 2.6의 새로운 통합 기능 중 하나입니다 $ 편집하다을 사용하는 것입니다. 당신은 2.6를 사용하는 경우, 당신은 당신이 큰 배열이있는 경우 당신에게 성능 문제가 발생할 수 있습니다 $ 언 와인드 필요하지 않습니다.

    db.test.aggregate([
        { $match: { 
             shapes: { $elemMatch: {color: "red"} } 
        }},
        { $redact : {
             $cond: {
                 if: { $or : [{ $eq: ["$color","red"] }, { $not : "$color" }]},
                 then: "$$DESCEND",
                 else: "$$PRUNE"
             }
        }}]);
    

    $ 편집하다 "는 문서 자체에 저장된 정보를 기반으로 문서의 내용을 제한합니다." 그래서 그것은 단지 내부 문서의 실행됩니다. 그것은 어느 컨텐츠 ($$ DESCEND) 또는 제거를 유지할 일치가있는 경우, $ 콘드에 귀하의 경우 조건에 일치하는 경우 그것은 기본적으로 문서의 하단에 상단 및 검사를 스캔 ($$ PRUNE).

    위의 예에서 첫번째 $ 일치 반환 전체 모양 배열, 그리고 $ 편집하다는 예상 된 결과로 아래로 제거합니다.

    참고 {$ 없습니다 : "$ 색상"} 그것뿐만 아니라 상단의 문서를 스캔하기 때문에, 필요하며, $ 편집하다이 최상위에 색상 필드를 찾을 수없는 경우이 문서 전체를 제거 할 수가 false를 반환 할 우리 원하지 않는다.

  5. ==============================

    5.더 나은 당신이 $ 슬라이스를 사용하여 배열 요소를 일치에서 조회 할 수 있습니다 그것은 배열의 중요한 객체를 반환하는 것이 도움이된다.

    더 나은 당신이 $ 슬라이스를 사용하여 배열 요소를 일치에서 조회 할 수 있습니다 그것은 배열의 중요한 객체를 반환하는 것이 도움이된다.

    db.test.find({"shapes.color" : "blue"}, {"shapes.$" : 1})
    

    당신은 요소의 인덱스를 알고있는 경우 $ 슬라이스 도움이 될 것입니다,하지만 때로는 당신이 원하는 중 배열 요소는 당신의 기준과 일치. 당신은 일치하는 요소를 반환 할 수 있습니다 은 $ 연산자.

  6. ==============================

    6.

     db.getCollection('aj').find({"shapes.color":"red"},{"shapes.$":1})
    

    OUTPUTS

    {
    
       "shapes" : [ 
           {
               "shape" : "circle",
               "color" : "red"
           }
       ]
    }
    
  7. ==============================

    7.MongoDB를 찾을의 구문은

    MongoDB를 찾을의 구문은

        db.<collection name>.find(query, projection);
    

    당신이 쓴 것을 두 번째 쿼리, 즉

        db.test.find(
        {shapes: {"$elemMatch": {color: "red"}}}, 
        {"shapes.color":1})
    

    당신이 돌출부에이 연산자를 사용하는 경우 다음 당신이 원하는 결과를 얻을 수있는 반면이 당신은 쿼리 부분에 $ elemMatch 연산자를 사용했다. 당신은 쿼리를 작성할 수 있습니다

         db.users.find(
         {"shapes.color":"red"},
         {_id:0, shapes: {$elemMatch : {color: "red"}}})
    

    이것은 당신에게 원하는 결과를 제공 할 것입니다.

  8. ==============================

    8.여기에 나는 좀 더 복잡한 사용을 추가 할.

    여기에 나는 좀 더 복잡한 사용을 추가 할.

    // Document 
    { 
    "_id" : 1
    "shapes" : [
      {"shape" : "square",  "color" : "red"},
      {"shape" : "circle",  "color" : "green"}
      ] 
    } 
    
    { 
    "_id" : 2
    "shapes" : [
      {"shape" : "square",  "color" : "red"},
      {"shape" : "circle",  "color" : "green"}
      ] 
    } 
    
    
    // The Query   
    db.contents.find({
        "_id" : ObjectId(1),
        "shapes.color":"red"
    },{
        "_id": 0,
        "shapes" :{
           "$elemMatch":{
               "color" : "red"
           } 
        }
    }) 
    
    
    //And the Result
    
    {"shapes":[
        {
           "shape" : "square",
           "color" : "red"
        }
    ]}
    
  9. ==============================

    9.당신은 쿼리를 실행해야합니다

    당신은 쿼리를 실행해야합니다

    db.test.find(
    {"shapes.color": "red"}, 
    {shapes: {$elemMatch: {color: "red"}}});
    

    이 쿼리의 출력은

    {
        "_id" : ObjectId("562e7c594c12942f08fe4192"),
        "shapes" : [ 
            {"shape" : "circle", "color" : "red"}
        ]
    }
    

    '빨간색': 당신이 그것을 예상대로 것이다는 일치 색상 것을 배열에서 정확한 필드를 제공합니다.

  10. ==============================

    10.$ 프로젝트와 함께이 더 적합한 다른 현명한 일치하는 요소는 문서의 다른 요소와 함께 몽둥이 될 것입니다.

    $ 프로젝트와 함께이 더 적합한 다른 현명한 일치하는 요소는 문서의 다른 요소와 함께 몽둥이 될 것입니다.

    db.test.aggregate(
      { "$unwind" : "$shapes" },
      { "$match" : {
         "shapes.color": "red"
      }},
    {"$project":{
    "_id":1,
    "item":1
    }}
    )
    
  11. ==============================

    11.

    db.test.find( {"shapes.color": "red"}, {_id: 0})
    
  12. from https://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection by cc-by-sa and MIT license