복붙노트

[MONGODB] MongoDB를 집계 방법 : 총 기록을 계산 얻을?

MONGODB

MongoDB를 집계 방법 : 총 기록을 계산 얻을?

나는 MongoDB의 레코드를 가져 오는에 대한 집계를 사용했다.

$result = $collection->aggregate(array(
  array('$match' => $document),
  array('$group' => array('_id' => '$book_id', 'date' => array('$max' => '$book_viewed'),  'views' => array('$sum' => 1))),
  array('$sort' => $sort),
  array('$skip' => $skip),
  array('$limit' => $limit),
));

내가 제한없이이 쿼리를 실행하면 다음 10 개 개의 레코드가 반입 될 것입니다. 하지만 난이 전체 레코드를 계산 좀하고 싶습니다 그래서 2로 제한을 유지하려는. 나는 집계에 어떻게 할 수 있습니까? 나에게 조언을 주시기 바랍니다. 감사

해결법

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

    1.이 페이지가 매겨진 결과를 얻을 수있는 가장 자주 묻는 질문 단일 쿼리에서 동시에 결과의 총 개수 중 하나입니다. 나는 마지막으로 LOL을 달성했을 때의 느낌은 설명 할 수 없다.

    이 페이지가 매겨진 결과를 얻을 수있는 가장 자주 묻는 질문 단일 쿼리에서 동시에 결과의 총 개수 중 하나입니다. 나는 마지막으로 LOL을 달성했을 때의 느낌은 설명 할 수 없다.

    $result = $collection->aggregate(array(
      array('$match' => $document),
      array('$group' => array('_id' => '$book_id', 'date' => array('$max' => '$book_viewed'),  'views' => array('$sum' => 1))),
      array('$sort' => $sort),
    
    // get total, AND preserve the results
      array('$group' => array('_id' => null, 'total' => array( '$sum' => 1 ), 'results' => array( '$push' => '$$ROOT' ) ),
    // apply limit and offset
      array('$project' => array( 'total' => 1, 'results' => array( '$slice' => array( '$results', $skip, $length ) ) ) )
    ))
    

    다음과 같이 보일 것입니다 결과 :

    [
      {
        "_id": null,
        "total": ...,
        "results": [
          {...},
          {...},
          {...},
        ]
      }
    ]
    
  2. ==============================

    2.v.3.4 때문에 MongoDB를 지금 '면'라는 이름의 새로운 통합 파이프 라인 연산자를 가지고 (나는) 생각하는 그 자신의 말로 :

    v.3.4 때문에 MongoDB를 지금 '면'라는 이름의 새로운 통합 파이프 라인 연산자를 가지고 (나는) 생각하는 그 자신의 말로 :

    특히이 경우,이 방법은 하나 이런 식으로 뭔가를 할 수있는 :

    $result = $collection->aggregate([
      { ...execute queries, group, sort... },
      { ...execute queries, group, sort... },
      { ...execute queries, group, sort... },
      $facet: {
        paginatedResults: [{ $skip: skipPage }, { $limit: perPage }],
        totalCount: [
          {
            $count: 'count'
          }
        ]
      }
    ]);
    

    그 결과 (예 : 총 100의 결과로)입니다 :

    [
      {
        "paginatedResults":[{...},{...},{...}, ...],
        "totalCount":[{"count":100}]
      }
    ]
    
  3. ==============================

    3.컬렉션의 총 수를 찾기 위해 사용합니다.

    컬렉션의 총 수를 찾기 위해 사용합니다.

    db.collection.aggregate( [
    { $match : { score : { $gt : 70, $lte : 90 } } },
    { $group: { _id: null, count: { $sum: 1 } } }
    ] );
    
  4. ==============================

    4.당신은 toArray 기능을 사용하여 전체 레코드를 계산하기위한 다음의 길이를 얻을 수 있습니다.

    당신은 toArray 기능을 사용하여 전체 레코드를 계산하기위한 다음의 길이를 얻을 수 있습니다.

    db.CollectionName.aggregate([....]).toArray().length
    
  5. ==============================

    5.총 페이지 수를 얻기 위해 $ 카운트 집계 파이프 라인 단계를 사용합니다 :

    총 페이지 수를 얻기 위해 $ 카운트 집계 파이프 라인 단계를 사용합니다 :

    검색어 :

    db.collection.aggregate(
      [
        {
          $match: {
            ...
          }
        },
        {
          $group: {
            ...
          }
        },
        {
          $count: "totalCount"
        }
      ]
    )
    

    결과:

    {
       "totalCount" : Number of records (some integer value)
    }
    
  6. ==============================

    6.나는 이런 식으로했다 :

    나는 이런 식으로했다 :

    db.collection.aggregate([
         { $match : { score : { $gt : 70, $lte : 90 } } },
         { $group: { _id: null, count: { $sum: 1 } } }
    ] ).map(function(record, index){
            print(index);
     });
    

    집계 그래서 그냥 루프를 배열을 반환하고 마지막 인덱스를 얻을 것이다.

    그리고 그 일을 다른 방법입니다 :

    var count = 0 ;
    db.collection.aggregate([
    { $match : { score : { $gt : 70, $lte : 90 } } },
    { $group: { _id: null, count: { $sum: 1 } } }
    ] ).map(function(record, index){
            count++
     }); 
    print(count);
    
  7. ==============================

    7.@Divergent가 제공하는 솔루션은 작업을 수행하지만, 내 경험에 2 개 쿼리를하는 것이 좋습니다 :

    @Divergent가 제공하는 솔루션은 작업을 수행하지만, 내 경험에 2 개 쿼리를하는 것이 좋습니다 :

    $$ ROOT를 밀어 큰 컬렉션에 대한 16메가바이트의 문서 메모리 제한에 $ 슬라이스 실행을 사용하여와 솔루션. 또한, 대형 컬렉션에 대한 두 개의 쿼리 함께 빠른 $$ ROOT 밀고와 함께보다 실행하는 것 같다. 당신은 (아마도 한 종류) 두 쿼리의 느린에 의해 제한됩니다, 그래서 당신은뿐만 아니라 병렬로 실행할 수 있습니다.

    - (I이 예에서 Node.js를 사용하지만 아이디어는 동일 주) I 2 개 쿼리와 통합 프레임 워크를 사용하여이 솔루션으로 정착

    var aggregation = [
      {
        // If you can match fields at the begining, match as many as early as possible.
        $match: {...}
      },
      {
        // Projection.
        $project: {...}
      },
      {
        // Some things you can match only after projection or grouping, so do it now.
        $match: {...}
      }
    ];
    
    
    // Copy filtering elements from the pipeline - this is the same for both counting number of fileter elements and for pagination queries.
    var aggregationPaginated = aggregation.slice(0);
    
    // Count filtered elements.
    aggregation.push(
      {
        $group: {
          _id: null,
          count: { $sum: 1 }
        }
      }
    );
    
    // Sort in pagination query.
    aggregationPaginated.push(
      {
        $sort: sorting
      }
    );
    
    // Paginate.
    aggregationPaginated.push(
      {
        $limit: skip + length
      },
      {
        $skip: skip
      }
    );
    
    // I use mongoose.
    
    // Get total count.
    model.count(function(errCount, totalCount) {
      // Count filtered.
      model.aggregate(aggregation)
      .allowDiskUse(true)
      .exec(
      function(errFind, documents) {
        if (errFind) {
          // Errors.
          res.status(503);
          return res.json({
            'success': false,
            'response': 'err_counting'
          });
        }
        else {
          // Number of filtered elements.
          var numFiltered = documents[0].count;
    
          // Filter, sort and pagiante.
          model.request.aggregate(aggregationPaginated)
          .allowDiskUse(true)
          .exec(
            function(errFindP, documentsP) {
              if (errFindP) {
                // Errors.
                res.status(503);
                return res.json({
                  'success': false,
                  'response': 'err_pagination'
                });
              }
              else {
                return res.json({
                  'success': true,
                  'recordsTotal': totalCount,
                  'recordsFiltered': numFiltered,
                  'response': documentsP
                });
              }
          });
        }
      });
    });
    
  8. ==============================

    8.이것은 여러 일치 조건 일 수

    이것은 여러 일치 조건 일 수

                const query = [
                    {
                        $facet: {
                        cancelled: [
                            { $match: { orderStatus: 'Cancelled' } },
                            { $count: 'cancelled' }
                        ],
                        pending: [
                            { $match: { orderStatus: 'Pending' } },
                            { $count: 'pending' }
                        ],
                        total: [
                            { $match: { isActive: true } },
                            { $count: 'total' }
                        ]
                        }
                    },
                    {
                        $project: {
                        cancelled: { $arrayElemAt: ['$cancelled.cancelled', 0] },
                        pending: { $arrayElemAt: ['$pending.pending', 0] },
                        total: { $arrayElemAt: ['$total.total', 0] }
                        }
                    }
                    ]
                    Order.aggregate(query, (error, findRes) => {})
    
  9. ==============================

    9.죄송합니다,하지만 난 당신이 두 개의 쿼리를 필요가 있다고 생각합니다. 총 전망에 대한 하나의 그룹화 레코드에 대한 또 하나.

    죄송합니다,하지만 난 당신이 두 개의 쿼리를 필요가 있다고 생각합니다. 총 전망에 대한 하나의 그룹화 레코드에 대한 또 하나.

    당신은 도움이 답을 찾을 수 있습니다

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

    10.

    //const total_count = await User.find(query).countDocuments();
    //const users = await User.find(query).skip(+offset).limit(+limit).sort({[sort]: order}).select('-password');
    const result = await User.aggregate([
      {$match : query},
      {$sort: {[sort]:order}},
      {$project: {password: 0, avatarData: 0, tokens: 0}},
      {$facet:{
          users: [{ $skip: +offset }, { $limit: +limit}],
          totalCount: [
            {
              $count: 'count'
            }
          ]
        }}
      ]);
    console.log(JSON.stringify(result));
    console.log(result[0]);
    return res.status(200).json({users: result[0].users, total_count: result[0].totalCount[0].count});
    
  11. from https://stackoverflow.com/questions/20348093/mongodb-aggregation-how-to-get-total-records-count by cc-by-sa and MIT license