복붙노트

[MONGODB] MongoDB의 응집을 이용하여 한계 정렬 각 그룹 [중복]

MONGODB

MongoDB의 응집을 이용하여 한계 정렬 각 그룹 [중복]

어떻게 정렬하여 MongoDB에서 각 그룹을 제한 할 수 있습니다.

데이터 아래 고려 :

Country:USA,name:xyz,rating:10,id:x
Country:USA,name:xyz,rating:10,id:y
Country:USA,name:xyz,rating:10,id:z
Country:USA,name:abc,rating:5,id:x
Country:India,name:xyz,rating:5,id:x
Country:India,name:xyz,rating:5,id:y
Country:India,name:abc,rating:10,id:z
Country:India,name:abc,rating:10,id:x

지금은 그룹 국가 별 및 분류 등급에 의한 것이라고 2에 의해 각 그룹의 데이터를 제한 할 수 있습니다.

그래서 대답은 다음과 같습니다

Country:USA
name:xyz,rating:10,id:x
name:xyz,rating:10,id:y
Country:India
name:abc,rating:10,id:x
name:abc,rating:10,id:z

난 단지이 사용하는 총 프레임 워크를 달성하고 싶다.

나는 평가에 대한 집계에 종류를 포함하여 시도했지만 단순히 쿼리를 처리 한 후 결과가 회전하지 않습니다.

해결법

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

    1.여기 당신의 최선의 선택은 (이상적으로 병렬) 각 "나라"에 대한 별도의 쿼리를 실행하고 결합 된 결과를 반환하는 것입니다. 쿼리는 매우 간단하며, 단지 평가 값에 정렬을 적용한 후 상위 2 값을 반환하고 매우 빠르게 전체 결과를 얻기 위해 여러 쿼리를 수행해야하는 경우에도 실행됩니다.

    여기 당신의 최선의 선택은 (이상적으로 병렬) 각 "나라"에 대한 별도의 쿼리를 실행하고 결합 된 결과를 반환하는 것입니다. 쿼리는 매우 간단하며, 단지 평가 값에 정렬을 적용한 후 상위 2 값을 반환하고 매우 빠르게 전체 결과를 얻기 위해 여러 쿼리를 수행해야하는 경우에도 실행됩니다.

    집계 프레임 워크는 현재와도 가까운 장래에,이에 적합하지 않습니다. 문제는 이러한 연산자가없는입니다 "한계"어떤 방법으로 어떤 그룹의 결과. 그래서이 작업을 수행하기 위해, 당신은 기본적으로 배열로 모든 컨텐츠를 밀어하고 "상위 N"그에서 값을 추출 $해야합니다.

    그렇게하기 위해 필요한 현재의 작업은 매우 끔찍한이며, 핵심 문제는 결과가 가능성이 가장 실제 데이터 소스에 대한 문서 당 16메가바이트의 BSON 제한을 초과 할 수 있습니다입니다.

    또한 때문에 당신이 지금 당장해야 할 것입니다 방법이에 N의 복잡성이있다. 그러나 불과 2 개 항목 설명합니다 :

    db.collection.aggregate([
        // Sort content by country and rating
        { "$sort": { "Country": 1, "rating": -1 } },
    
        // Group by country and push all items, keeping first result
        { "$group": {
            "_id": "$Country",
            "results": {
                "$push": {
                    "name": "$name", 
                    "rating": "$rating",
                    "id": "$id"
                }
            },
            "first": { 
                "$first": {
                    "name": "$name", 
                    "rating": "$rating",
                    "id": "$id"
                }
            }
        }},
    
        // Unwind the array
        { "$unwind": "results" },
    
        // Remove the seen result from the array
        { "$redact": {
            "$cond": {
                "if": { "$eq": [ "$results.id", "$first.id" ] },
                "then": "$$PRUNE",
                "else": "$$KEEP"
            }
        }},
    
        // Group to return the second result which is now first on stack
        { "$group": {
            "_id": "$_id",
            "first": { "$first": "$first" },
            "second": { 
                "$first": {
                    "name": "$results.name", 
                    "rating": "$results.rating",
                    "id": "$results.id"
                }
            }
        }},
    
        // Optionally put these in an array format
        { "$project": {
            "results": { 
                "$map": {
                    "input": ["A","B"],
                    "as": "el",
                    "in": {
                        "$cond": {
                            "if": { "$eq": [ "$$el", "A" ] },
                            "then": "$first",
                            "else": "$second"
                        }
                    }
                }
            }
        }}
    ])
    

    즉, 결과 만이 아니 좋은 접근 방식을 얻고, 더 높은 한계 또는 경우에도 그룹은 n 개의 결과가 어떤 경우에 반환하는 것보다 아마도 더 적은이에 대한 반복으로 훨씬 더 복잡한 가져옵니다.

    글을 쓰는 현재 개발 시리즈 (3.1.X)이 좀 더 간단하게하는 $ 슬라이스 연산자를 가지고 있지만, 여전히 같은 "크기"함정이 있습니다 :

    db.collection.aggregate([
        // Sort content by country and rating
        { "$sort": { "Country": 1, "rating": -1 } },
    
        // Group by country and push all items, keeping first result
        { "$group": {
            "_id": "$Country",
            "results": {
                "$push": {
                    "name": "$name", 
                    "rating": "$rating",
                    "id": "$id"
                }
            }
        }},
        { "$project": {
            "results": { "$slice": [ "$results", 2 ] }
        }}
    ])
    

    그러나 통합 프레임 워크는 "제한"$ 푸시 또는 유사한 그룹 "제한"연산자에 의해 생성 된 항목의 수에 몇 가지 방법이 기본적으로 때까지, 다음 통합 프레임 워크는 정말 이러한 유형의 문제에 대한 최적의 솔루션이 아닙니다.

    이 같은 간단한 쿼리 :

    db.collection.find({ "Country": "USA" }).sort({ "rating": -1 }).limit(1)
    

    조합 된 결과 스레드의 이벤트 루프에 의해 병렬 처리에 이상적으로 각각 별개의 국가 실행하고 지금 최적의 방식을 생성한다. 그들은 단지 집계 프레임 워크는 아직 같은 그룹에서 처리 할 수없는 큰 문제이다, 필요한 것을 가져옵니다.

    지원 모습 대신 선택한 언어에 가장 최적의 방법이 "통합 쿼리 결과를"이렇게하려면, 그것은 훨씬 덜 복잡하고 훨씬 더 성능이 좋은 집계 프레임 워크에서이 던지는 것보다 될 것입니다.

  2. from https://stackoverflow.com/questions/33458107/limit-and-sort-each-group-by-in-mongodb-using-aggregation by cc-by-sa and MIT license