सवाल 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 के रूप में सीमा रखना चाहता हूं। तो मैं कुल रिकॉर्ड गिनती प्राप्त करना चाहता हूं। मैं एकत्रीकरण के साथ कैसे कर सकता हूं? कृपया मुझे सलाह दें। धन्यवाद


44
2017-12-03 10:06


मूल


परिणाम केवल 2 के समान होने पर क्या दिखेंगे? - WiredPrairie


जवाब:


यह अंकगणित परिणाम प्राप्त करने और एकल क्वेरी में परिणामों की कुल संख्या प्राप्त करने के लिए सबसे अधिक पूछे जाने वाले प्रश्नों में से एक है। मैं समझ नहीं पा रहा हूं कि आखिर में जब मैंने इसे एलओएल हासिल किया तो मुझे कैसा लगा।

$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": [
      {...},
      {...},
      {...},
    ]
  }
]

64
2017-09-30 06:15



इस पर दस्तावेज़ीकरण: docs.mongodb.com/v3.2/reference/operator/aggregation/group/... ... ध्यान दें कि इस दृष्टिकोण के साथ, संपूर्ण गैर-पृष्ठित परिणाम सेट 16 एमबी में फिट होना चाहिए। - btown
यह शुद्ध सोना है! मैं इस काम को करने की कोशिश कर नरक के माध्यम से जा रहा था। - Henrique Miranda
धन्यवाद, हेनरिक मिरांडा। - Anurag pareek
धन्यवाद भाई ! मुझे बस चाहिए { $group: { _id: null, count: { $sum:1 }, result: { $push: '$$ROOT' }}} (के बाद डालें {$group:{}} गिनती कुल खोज के लिए। - Liberateur
आप परिणाम सेट पर सीमा कैसे लागू करते हैं? परिणाम अब एक नेस्टेड सरणी है - valen


संग्रह में कुल गिनती खोजने के लिए इसका इस्तेमाल करें।

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

34
2017-12-03 10:19



धन्यवाद। लेकिन, मैंने इसी कोडिंग गिनती की गणना प्राप्त करने के लिए अपने कोडिंग में "विचार" का उपयोग किया है (यानी, समूह 1 => 2 रिकॉर्ड, समूह 3 => 5 रिकॉर्ड और इसी तरह)। मैं रिकॉर्ड गिनती प्राप्त करना चाहता हूं (यानी कुल: 120 रिकॉर्ड)। आशा है कि आप समझ गए .. - user2987836


आप ऐरे फ़ंक्शन का उपयोग कर सकते हैं और उसके बाद कुल रिकॉर्ड गिनती के लिए इसकी लंबाई प्राप्त कर सकते हैं।

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

12
2018-04-25 06:31



मेरे लिए काम किया धन्यवाद। - Shashank
Perfomances के लिए अनुशंसित नहीं है ... अगर आपके पास बड़ा डीबी है। - Liberateur
हालांकि यह "उचित" समाधान के रूप में काम नहीं कर सकता है, लेकिन इससे मुझे कुछ डीबग करने में मदद मिली - यह काम करता है, भले ही यह 100% समाधान न हो। - Johann Marx
यह विशाल डेटा के लिए काम नहीं कर रहा है - Mustafa Mohammadi


मैंने इसे इस तरह से किया:

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);

8
2018-06-27 05:34



fwiw आपको जरूरत नहीं है var घोषणा न ही map कहते हैं। आपके पहले उदाहरण की पहली 3 पंक्तियां पर्याप्त हैं। - Madbreaks


चूंकि v.3.4 (मुझे लगता है) मोंगोडीबी के पास अब एक नया एकत्रीकरण पाइपलाइन ऑपरेटर है जिसका नाम 'पहलू'जो अपने शब्दों में:

इनपुट दस्तावेजों के एक ही सेट पर एक ही चरण में एकाधिक एकत्रीकरण पाइपलाइनों को संसाधित करता है। आउटपुट दस्तावेज़ में प्रत्येक उप-पाइपलाइन का अपना क्षेत्र होता है जहां इसके परिणाम दस्तावेजों की एक सरणी के रूप में संग्रहीत होते हैं।

इस विशेष मामले में, इसका मतलब है कि कोई ऐसा कुछ कर सकता है:

$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}]
  }
]

6
2018-03-26 04:19



यह 3.4 काम करता है, यह स्वीकार्य उत्तर होना चाहिए - Adam Reis


@Divergent द्वारा प्रदान किया गया समाधान काम करता है, लेकिन मेरे अनुभव में 2 प्रश्न होने के लिए बेहतर है:

  1. पहले फ़िल्टर किए गए तत्वों की संख्या प्राप्त करने के लिए फ़िल्टर करके फ़िल्टरिंग के लिए और फिर समूहबद्ध करना। यहां फ़िल्टर न करें, यह अनावश्यक है।
  2. दूसरी क्वेरी जो फिल्टर, प्रकार और पेजिनेट करती है।

$$ रूट को धक्का देने और $ स्लाइस का उपयोग करने के साथ समाधान बड़े संग्रह के लिए 16 एमबी की दस्तावेज़ स्मृति सीमा में चलाता है। इसके अलावा, बड़े संग्रह के लिए दो प्रश्न एक साथ $$ रूट धक्का देने के साथ तेजी से चलते प्रतीत होते हैं। आप उन्हें समानांतर में भी चला सकते हैं, इसलिए आप केवल दो प्रश्नों की धीमी गति से सीमित हैं (शायद वह जो एक प्रकार है)।

मैं 2 समाधान और एकत्रीकरण ढांचे का उपयोग करके इस समाधान के साथ बस गया हूं (नोट - मैं इस उदाहरण में node.js का उपयोग करता हूं, लेकिन विचार समान है):

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
            });
          }
      });
    }
  });
});

5
2018-02-09 17:42





क्षमा करें, लेकिन मुझे लगता है कि आपको दो प्रश्नों की आवश्यकता है। कुल विचारों के लिए एक और समूहबद्ध रिकॉर्ड के लिए दूसरा।

आप उपयोगी पा सकते हैं यह जवाब


0
2017-12-03 12:42



धन्यवाद..मुझे ऐसा लगता है..लेकिन, एकत्रीकरण के साथ कोई विकल्प नहीं है .. :( - user2987836
मैं एक समान स्थिति में भाग गया। 2 प्रश्न करने के अलावा कोई जवाब नहीं था। :( stackoverflow.com/questions/20113731/... - astroanu


एकत्रीकरण परिणाम की कुल गणना प्राप्त करने के लिए $ गिनती ऑपरेटर का उपयोग करें

प्रश्न:

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

परिणाम:

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

0
2017-07-17 13:33