복붙노트

[MONGODB] 어떻게하여 MongoDB의 하위 문서의 모든 필드를 요약하는?

MONGODB

어떻게하여 MongoDB의 하위 문서의 모든 필드를 요약하는?

내가 MongoDB를에 db.collection.aggregate를 사용할 때 나는 문제가있어.

나는 데이터 구조 등이있다 :

_id:...

Segment:{
  "S1":1,
  "S2":5,
  ...
  "Sn":10
}

이 세그먼트에서 다음을 의미한다 : 나는 숫자 값을 가진 여러 개의 하위 속성이있을 수 있습니다. 나는 1 + 5 + ... + 10로를 요약하고 싶습니다

문제는 : 나는 각 문서의 세그먼트 번호가 다르기 때문에, 서브가 이름을 속성에 대해 확실하지 않다. 그래서 각 세그먼트의 이름을 나열 할 수 없습니다. 난 그냥 함께 모든 값 합계를 for 루프 같은 것을 사용하고 싶습니다.

나는 쿼리를 같은 시도 :

db.collection.aggregate([

  {$group:{
    _id:"$Account",

    total:{$sum:"$Segment.$"}
])

그러나 그것은 작동하지 않습니다.

해결법

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

    1.당신은 임의의 필드 이름을 가지고 고전적인 실수를했다. MongoDB를은 "스키마 무료"이지만, 그것은 당신이 당신의 스키마에 대해 생각 할 필요가 없습니다 의미하지 않는다. 키 이름은 설명, 그리고 귀하의 경우, f.e.에서한다 "S2는"정말 뜻 아무것도하지 않습니다. 쿼리 및 운영의 대부분의 종류를 수행하기 위해서는 다음과 같은 데이터를 저장하기 위해 당신에게 스키마를 재 설계해야합니다 :

    당신은 임의의 필드 이름을 가지고 고전적인 실수를했다. MongoDB를은 "스키마 무료"이지만, 그것은 당신이 당신의 스키마에 대해 생각 할 필요가 없습니다 의미하지 않는다. 키 이름은 설명, 그리고 귀하의 경우, f.e.에서한다 "S2는"정말 뜻 아무것도하지 않습니다. 쿼리 및 운영의 대부분의 종류를 수행하기 위해서는 다음과 같은 데이터를 저장하기 위해 당신에게 스키마를 재 설계해야합니다 :

    _id:...
    Segment:[
        { field: "S1", value: 1 },
        { field: "S2", value: 5 },
        { field: "Sn", value: 10 },
    ]
    

    그런 다음 쿼리 등을 실행할 수 있습니다 :

    db.collection.aggregate( [
        { $unwind: "$Segment" },
        { $group: {
            _id: '$_id', 
            sum: { $sum: '$Segment.value' } 
        } } 
    ] );
    

    어느 다음 (질문의 유일한 문서) 이런 일에 결과 :

    {
        "result" : [
            {
                "_id" : ObjectId("51e4772e13573be11ac2ca6f"),
                "sum" : 16
            }
        ],
        "ok" : 1
    }
    
  2. ==============================

    2.몽고 3.4을 시작, 이것은 같은 $ 그룹으로 비싼 작업을하지 않도록하여 인라인 작업을 적용하고에 의해 달성 될 수있다 :

    몽고 3.4을 시작, 이것은 같은 $ 그룹으로 비싼 작업을하지 않도록하여 인라인 작업을 적용하고에 의해 달성 될 수있다 :

    // { _id: "xx", segments: { s1: 1, s2: 3, s3: 18, s4: 20 } }
    db.collection.aggregate([
      { $addFields: {
          total: { $sum: {
            $map: { input: { $objectToArray: "$segments" }, as: "kv", in: "$$kv.v" }
          }}
      }}
    ])
    // { _id: "xx", total: 42, segments: { s1: 1, s2: 3, s3: 18, s4: 20 } }
    

    아이디어는 배열로 물체 (합계 번호를 포함)을 변환한다. 이 몽고 3.4.4부터 $ objectToArray의 역할이며, 변환 {S1 : 1, S2 : 3, ...}, {K [{ "S1", V 1 K}로 "S2" V : 3}, ...]. 이 방법은, 우리는 우리가 자신의 "V"필드를 통해 값에 액세스 할 수 있기 때문에 필드 이름에 대해 신경 쓸 필요가 없습니다.

    오브젝트 대신 배열을 갖는 요소를 요약 할 수있는위한 첫 단계이다. 그러나 $ objectToArray으로 얻은 요소는 개체와 간단하지 정수입니다. 우리는 매핑합니다 ($지도 작업) 자신의 "V"필드의 값을 추출하기 위해 이러한 배열 요소에 의해이 전달받을 수 있습니다. 이러한 배열을 만드는 경우에 우리의 결과에 어떤 : 1, 3, 18, 42].

    마지막으로, $ 합 연산을 사용하여,이 배열 내의 요소를 합산하는 단순한 문제이다.

  3. from https://stackoverflow.com/questions/17661461/how-to-sum-every-fields-in-a-sub-document-of-mongodb by cc-by-sa and MIT license