복붙노트

[MONGODB] 방법 MongoDB를 가진 하위 필터링 배열 [중복]

MONGODB

방법 MongoDB를 가진 하위 필터링 배열 [중복]

이 같은 하위 문서의 배열을

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 1
        },
        {
            "a" : 2
        },
        {
            "a" : 3
        },
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]
}

A의 수 있습니까 필터 하위 문서> 3

아래의 결과를 기대하는 내

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]
}

나는 $ elemMatch하지만 반환 배열의 첫 번째 일치하는 요소를 사용하려고

내 쿼리 :

db.test.find( { _id" : ObjectId("512e28984815cbfcb21646a7") }, { 
    list: { 
        $elemMatch: 
            { a: { $gt:3 } 
            } 
    } 
} )

그 결과, 배열에 하나 개의 요소를 리턴

{ "_id" : ObjectId("512e28984815cbfcb21646a7"), "list" : [ { "a" : 4 } ] }

나는 $ 일치하지만 작업으로 집계 사용하려고

db.test.aggregate({$match:{_id:ObjectId("512e28984815cbfcb21646a7"), 'list.a':{$gte:5}  }})

이 배열의 모든 요소를 ​​반환이다

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 1
        },
        {
            "a" : 2
        },
        {
            "a" : 3
        },
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]
}

배열 할 수 있습니까 필터 요소는 결과 예상대로 결과를 얻으려면?

해결법

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

    1.골재를 사용하는 것은 올바른 접근 방식이지만, 당신은 당신이 개별 요소를 필터링 한 후 다시 함께 넣어 $ 그룹을 사용할 수 있도록 $ 일치를 적용하기 전에 목록 배열을 언 와인드 $해야합니다

    골재를 사용하는 것은 올바른 접근 방식이지만, 당신은 당신이 개별 요소를 필터링 한 후 다시 함께 넣어 $ 그룹을 사용할 수 있도록 $ 일치를 적용하기 전에 목록 배열을 언 와인드 $해야합니다

    db.test.aggregate([
        { $match: {_id: ObjectId("512e28984815cbfcb21646a7")}},
        { $unwind: '$list'},
        { $match: {'list.a': {$gt: 3}}},
        { $group: {_id: '$_id', list: {$push: '$list.a'}}}
    ])
    

    출력 :

    {
      "result": [
        {
          "_id": ObjectId("512e28984815cbfcb21646a7"),
          "list": [
            4,
            5
          ]
        }
      ],
      "ok": 1
    }
    

    MongoDB를 3.2 업데이트

    3.2 릴리스부터 만 달러 (A $) 프로젝트 중 원하는 목록 요소를 포함 효율적이 더 많은 일을 새로운 $ 필터 집계 연산자를 사용할 수 있습니다 :

    db.test.aggregate([
        { $match: {_id: ObjectId("512e28984815cbfcb21646a7")}},
        { $project: {
            list: {$filter: {
                input: '$list',
                as: 'item',
                cond: {$gt: ['$$item.a', 3]}
            }}
        }}
    ])
    
  2. ==============================

    2.여러 일치하는 하위 문서가 필요한 경우 위 솔루션은 가장 잘 작동합니다. 단일 일치하는 하위 문서를 출력으로 필요한 경우 $ elemMatch도 매우 사용 온다

    여러 일치하는 하위 문서가 필요한 경우 위 솔루션은 가장 잘 작동합니다. 단일 일치하는 하위 문서를 출력으로 필요한 경우 $ elemMatch도 매우 사용 온다

    db.test.find({list: {$elemMatch: {a: 1}}}, {'list.$': 1})
    

    결과:

    {
      "_id": ObjectId("..."),
      "list": [{a: 1}]
    }
    
  3. ==============================

    3.$ 필터 집계를 사용하여

    $ 필터 집계를 사용하여

    db.test.aggregate([
        {$match: {"list.a": {$gt:3}}}, // <-- match only the document which have a matching element
        {$project: {
            list: {$filter: {
                input: "$list",
                as: "list",
                cond: {$gt: ["$$list.a", 3]} //<-- filter sub-array based on condition
            }}
        }}
    ]);
    
  4. from https://stackoverflow.com/questions/15117030/how-to-filter-array-in-subdocument-with-mongodb by cc-by-sa and MIT license