简体   繁体   中英

How to obtain pagination for the Mongo Aggregate

I have been using flask-paginate for pagination and Mongo DB as database:

In view.py page

from flask_paginate import Pagination, get_page_args

@app.route('/test',methods=['GET','POST'])
def searchindex():
    page, per_page, offset = get_page_args()
    pipeline = [{
    '$match': {
       "meanings.speech_part":word_type,
       "$expr": { "$gt": [ { "$strLenCP": "$word" }, word_length ] }
    }}]
    cursor_objects = db['test'].aggregate(pipeline)
    cursor_objects_list=list(cursor_objects)
    pagination = Pagination(page=page, total=len(cursor_objects_list),per_page=per_page,offset=offset,record_name='words')
    return render_template('index.html',data=cursor_objects_list,pagination=pagination)

In index.html :

{{ pagination.info }}
{{ pagination.links }}

{% for word in data %}
  <tr>
    <td>{{ loop.index + pagination.skip }}</td>
    <td> {{ word['word'] }}</td>
  </tr>
{% endfor %}

while I do this all the results are shown at once as :

在此处输入图片说明

Even clicking on 2 (page 2) shows the same results but number range is changed as :

在此处输入图片说明

I am stuck where i have done it wrong, Is the limit applied to the aggregate is the question on my head?

Any help is appreciated ,TIA

It's recommended to apply $sort operator for correct pagination.

Probably you are getting different result for every execution.

Try MongoDB way. Just add as last stages $skip and $limit to aggregation pipeline (imagine you have >1M records) and calculate total result separately:

#We add $skip and $limit
pipeline = [
  {
    '$match': {
       "meanings.speech_part":word_type,
       "$expr": { "$gt": [ { "$strLenCP": "$word" }, word_length ] }
    }
  },
  {'$sort': {'_id': 1}},
  {'$skip': page * per_page},
  {'$limit': per_page}
]

#We add $count
count_pipeline = [
  {
    '$match': {
       "meanings.speech_part":word_type,
       "$expr": { "$gt": [ { "$strLenCP": "$word" }, word_length ] }
    }
  },
  {'$count': "total"}
]

Now, we count total recods without $skip and $limit neither $sort .

pagination = Pagination(page=page, total=list(db['test'].aggregate(count_pipeline))[0].total, per_page=per_page, offset=offset, record_name='words')
return render_template('index.html', data=cursor_objects_list, pagination=pagination)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM