복붙노트

[MONGODB] 통합 프레임 워크에서 객체를 언 와인드 $

MONGODB

통합 프레임 워크에서 객체를 언 와인드 $

MongoDB의 통합 프레임 워크, 나는 물체 (예. JSON의 컬렉션)에서 $ 언 와인드 연산자를 사용하는 기대했다. 이 가능처럼 보이지 않는, 해결 방법은 무엇입니까? 이를 구현하기위한 계획이 있습니까?

예를 들어, 통합 문서에서 문서를들을. > 평가 - 사용자로부터 맵 추가 필드 "등급"이 가정하자. 각 사용자의 평균 등급을 계산 수 있을까?

이 외, 꽤 집계 프레임 워크와 함께 기뻐하고있다.

업데이트 : 여기에 요청에 따라 내 JSON 수집의 단순화 된 버전입니다. 나는 게놈 데이터를 저장하고있다. 가장 일반적인 조회가 임의의 사람 유전자형을 얻을 수 있기 때문에 정말, 유전자형 배열 할 수 없습니다.

variants: [

    {
        name: 'variant1', 
        genotypes: {

            person1: 2,
            person2: 5,
            person3: 7,

        }
    }, 

    {
        name: 'variant2', 
        genotypes: {

            person1: 3,
            person2: 3,
            person3: 2,

        }
    }

]

해결법

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

    1.당신이 통합 프레임 워크를 설명하는 계산의 유형을 할 수 없습니다 - 비 배열에 대한 $ 언 와인드 방법이 없기 때문에이 아니다. 사람하더라도 : 값 객체 배열에있는 문서를했다, $ 언 와인드는 도움이되지 것입니다.

    당신이 통합 프레임 워크를 설명하는 계산의 유형을 할 수 없습니다 - 비 배열에 대한 $ 언 와인드 방법이 없기 때문에이 아니다. 사람하더라도 : 값 객체 배열에있는 문서를했다, $ 언 와인드는 도움이되지 것입니다.

    기능은 "에 의해 그룹은"(MongoDB의 또는 관계형 데이터베이스 여부) 필드 또는 컬럼의 값에 이루어집니다. 다른 필드의 값을 기준으로 등 필드와 합계 / 평균 /의 값을 기준으로 우리는 그룹.

    간단한 예를 들어 당신이 제안 무엇의 변형이며, 등급 필드는 아니지만 평가에하지만,이 같은 배열로 사용자의지도로, 예제 문서 컬렉션에 추가 :

    { title : title of article", ...
      ratings: [
             { voter: "user1", score: 5 },
             { voter: "user2", score: 8 },
             { voter: "user3", score: 7 }
      ]
    }
    

    이제이 함께 집계 할 수 있습니다 :

    [ {$unwind: "$ratings"},
      {$group : {_id : "$ratings.voter", averageScore: {$avg:"$ratings.score"} } } 
    ]
    

    당신이 다음과 같을 것입니다 설명하지만이 예제는 구조 :

    { title : title of article", ...
      ratings: {
             user1: 5,
             user2: 8,
             user3: 7
      }
    }
    

    심지어이 :

    { title : title of article", ...
      ratings: [
             { user1: 5 },
             { user2: 8 },
             { user3: 7 }
      ]
    }
    

    이 긴장을 풀고 $ 수있다하더라도, 여기에 집계 아무것도 없다. 당신은 모든 가능한 키 (사용자)의 전체 목록을 알고하지 않는 한이와 함께 많은 일을 할 수 없다. [*]

    당신이 무엇을 유사한 관계형 DB 스키마는 다음과 같습니다

    CREATE TABLE T (
       user1: integer,
       user2: integer,
       user3: integer
       ...
    );
    

    의 수행 될 수없는 그 무엇, 그 대신 우리는이 작업을 수행 할 것입니다 :

    CREATE TABLE T (
       username: varchar(32),
       score: integer
    );
    

    이제 우리는 SQL을 사용하여 집계 :

    T 그룹의 이름으로 사용자 이름, 평균 (점수)를 선택;

    그 반대로 키에 프로젝트 값으로 능력 - 당신은 미래에 통합 프레임 워크에서이 작업을 수행 할 수 있습니다 MongoDB를위한 개선 요청이 있습니다. 한편, 항상 감소 /가지도한다.

    [*]가이 모든 고유 키를 알고있는 경우 (이 방법과 유사한 방법으로 모든 고유 키를 찾을 수 있습니다)을 할 수있는 복잡한 방법입니다하지만 당신은 모든 키를 알고 있다면 당신은뿐만 아니라 단지의 질의 시퀀스를 실행할 수 있습니다 폼 db.articles.find이 ({ "ratings.user1는": {$가 존재 : TRUE}}, {_ ID : 0, "ratings.user1": 1}) 각 userX에 대한 모든 평가를 반환하고 요약 할 수 있으며 그 평균을 단순히 충분한보다는 통합 프레임 워크를 필요로 매우 복잡한 프로젝션을한다.

  2. ==============================

    2.3.4.4 때문에, 당신은 $ objectToArray를 사용하여 배열에 객체를 변환 할 수 있습니다

    3.4.4 때문에, 당신은 $ objectToArray를 사용하여 배열에 객체를 변환 할 수 있습니다

    만나다: https://docs.mongodb.com/manual/reference/operator/aggregation/objectToArray/

  3. ==============================

    3.이것은 오래된 질문이지만, 나는 사람들이 유용하게 사용할 수 있음을 시행 착오를 통해 정보의 재미있는 이야기를 통해 실행했습니다.

    이것은 오래된 질문이지만, 나는 사람들이 유용하게 사용할 수 있음을 시행 착오를 통해 정보의 재미있는 이야기를 통해 실행했습니다.

    그것은 파서 이런 식으로 장난에 의해 더미 값에 긴장을 실제로 가능합니다 :

    db.Opportunity.aggregate(
      { $project: {
            Field1: 1, Field2: 1, Field3: 1,
            DummyUnwindField: { $ifNull: [null, [1.0]] }
        }
      },
      { $unwind: "$DummyUnwindField" }
    );
    

    이것은 상관없이 값이 존재하는지 여부, 문서마다 1 개 행을 생성한다. 당신은 당신이 원하는 결과를 생성하기 위해이 함께 할 수 어설프게 수 있습니다. 나는 그들이 불가능 결과를 얻을 수 있습니다 오히려 노동 조합보다 교차로로 결합하거나,하지만 슬프게도, 지난 $ 언 와인드 승리 (일종의 개의 발광 () 맵 / 감소 등)에 여러 $의 풀어서이 결합 기대했던 I 찾고 있었다. 나는 그것이 내가 그것을 사용하는 기대했다 하나의 유스 케이스에 맞지 않는 슬프게도 집계 프레임 워크 기능에 실망하고 (이 지역에 StackOverflow에 대한 질문을 많이처럼 이상하게 보인다는 요구하고있다) - 주문 결과를 일치를 기반으로 율. 성능이 가난한지도 것 줄일 개선은이 모든 기능은 불필요한 만들었습니다.

  4. ==============================

    4.이것은 내가 발견 및 확장 된 것입니다.

    이것은 내가 발견 및 확장 된 것입니다.

    db.copyDatabase('livedb' , 'experimentdb')
    
    db.getCollection('experimentcollection').find({}).forEach(function(e){
        if(e.store){
            e.ratings = [e.ratings]; //Objects name to be converted to array eg:ratings
            db.experimentcollection.save(e);
        }
    })
    
    var flatArray = [];
    
    var data = db.experimentcollection.find().toArray();
    
    for (var index = 0; index < data.length; index++) {
    
      var flatObject = {};
    
      for (var prop in data[index]) {
    
        var value = data[index][prop];
    
        if (Array.isArray(value) && prop === 'ratings') {
          for (var i = 0; i < value.length; i++) {
            for (var inProp in value[i]) {
              flatObject[inProp] = value[i][inProp];
            }
          }
        }else{
            flatObject[prop] = value;
        }
      }
      flatArray.push(flatObject);
    }
    
    printjson(flatArray);
    
  5. from https://stackoverflow.com/questions/11189243/unwind-an-object-in-aggregation-framework by cc-by-sa and MIT license