Пропустить и ограничить разбиение на страницы для агрегата Mongo

Я работаю над разбиением на страницы в фляге (фреймворк Python), используя флягу-пагинацию (только для ссылки)

Я могу выполнить разбиение на страницы только для запроса find, как показано ниже:

from flask_paginate import Pagination
from flask_paginate import get_page_args

def starting_with_letter(letter):
    page, per_page, offset = get_page_args()
    collection_name=letter.lower()+'_collection'
    words=db[collection_name]
    data_db=words.find()
    data=data_db.limit(per_page).skip(offset) '''Here I have achieved the limit and skip'''
    pagination = Pagination(page=page, total=data.count(),per_page=per_page,offset=offset,record_name='words')
    return render_template('startingwords.html',data=data,pagination=pagination)

Но я не могу сделать то же самое для агрегата здесь:

def test():
    page, per_page, offset = get_page_args()
    cursor_list=[]  '''appending each cursor in iteration of for loop '''
    collections=db.collection_names()
    for collection in collections:
        cursor_objects = db[collection].aggregate([
                {
                    "$match": {
                        "$expr": {"$eq": [{"$strLenCP": "$word"}, 6]}
                    }
                },
                            {"$skip": offset},    
                            {"$limit": per_page}

            ])
        for cursor in cursor_objects:
            cursor_list.append(cursor)
    pagination = Pagination(page=page, total=len(cursor_list),per_page=per_page,offset=offset,record_name='words')
    return render_template('lettersearch.html',data=cursor_list,pagination=pagination)

Результаты отображаются как:

введите здесь описание изображения

Здесь все результаты 39 показаны на одной странице.

При нажатии page 2 он показал:

введите здесь описание изображения

Примечание. По умолчанию flask-paginate изначально устанавливает per_page как 10, а offset как 0.

после ссылки на многие ссылки, которые я пробовал:

размещение skip и limit выше match, что в любом случае неправильно

Также узнал, что за limit всегда следует skip

Я застрял с этим, любая помощь приветствуется


person Codenewbie    schedule 03.01.2020    source источник
comment
Пожалуйста, этот код pageSize = param.pageSize; //10 pageNo = param.pageNo; //1,2,3,4,5 const skip = pageSize * (pageNo - 1); константа skipCond = {}; skipCond.$skip = пропустить; commonWhereCond.push(skipCond); постоянный предел = {}; лимит. $ лимит = размер страницы; commonWhereCond.push (лимит);   -  person Mahesh Bhatnagar    schedule 03.01.2020
comment
@MaheshBhatnagar извините, не смог понять формат, не могли бы вы опубликовать ответ, пожалуйста   -  person Codenewbie    schedule 03.01.2020
comment
означает, что вы можете получить значение пропуска, используя номер страницы. например: const skip = pageSize * (pageNo - 1); // pazesize =10, pageNo=1/2/3/4/5 const skipCond = {}; skipCond.$skip = пропустить; commonWhereCond.push(skipCond);   -  person Mahesh Bhatnagar    schedule 03.01.2020
comment
Здесь пропускайте инкременты сами по себе, не беспокойтесь о них, но дело в лимите, и пропуск здесь не работает для агрегата.   -  person Codenewbie    schedule 03.01.2020
comment
Хорошо, я проверяю   -  person Mahesh Bhatnagar    schedule 03.01.2020
comment
Скажите, пожалуйста, что выводит агрегат с лимитом и пропуском?   -  person Mahesh Bhatnagar    schedule 03.01.2020
comment
отображаются все записи, у меня всего 39, и я получаю 39 после лимита и тоже пропускаю   -  person Codenewbie    schedule 03.01.2020
comment
Пожалуйста, используйте этот код db[collection].aggregate([ {$limit:10} ])   -  person Mahesh Bhatnagar    schedule 03.01.2020
comment
Я пробовал всеми возможными способами, дружище, но ни один из них не работал   -  person Codenewbie    schedule 03.01.2020


Ответы (1)


Ваша проблема не с skip() и limit(); это работает нормально. Проблема в вашей общей логике; вы повторяете все 39 коллекций в первом цикле, а затем добавляете каждый результат агрегации в cursor_list.

Я не могу понять логику того, что вы пытаетесь сделать, так как первый пример ищет в коллекции слов, а второй ищет во всех коллекциях поле слова; с учетом сказанного вы, вероятно, можете упростить свой подход к чему-то вроде:

offset = 0
per_page = 10
collections = db.list_collection_names()
#
# Add some logic on the collections array to filter what is needed 
#
print(collections[offset:offset+per_page])

РЕДАКТИРОВАТЬ, чтобы отразить комментарии. Полный рабочий пример функции для выполнения этого. Нет необходимости в запросе агрегации — это добавляет сложности.

from pymongo import MongoClient
from random import randint

db = MongoClient()['testdatabase1']

# Set up some data
for i in range(39):
    coll_name = f'collection{i}'
    db[coll_name].delete_many({}) # Be careful; testing only; this deletes your data
    for k in range (randint(0, 2)):
        db[coll_name].insert_one({'word': '123456'})

# Main function
def test(offset, per_page, word_to_find):
    found = []
    collections = db.list_collection_names()
    for collection in sorted(collections):
        if db[collection].find_one({word_to_find: { '$exists': True}}) is not None:
            found.append(collection)

    print(found[offset:offset+per_page])

test(offset=0, per_page=10, word_to_find='word')
person Belly Buster    schedule 03.01.2020
comment
Причина, по которой я добавляю, заключается в том, что я хочу использовать это как data при отображении шаблона здесь как: return render_template('lettersearch.html',data=cursor_list,pagination=pagination) - person Codenewbie; 03.01.2020
comment
Как бы вы сделали это без дальнейшего добавления ? Я хочу проверить слово во всех коллекциях? та же логика в вопросе, как я мог сделать, как вы сказали? - person Codenewbie; 03.01.2020
comment
проверить какое слово? - person Belly Buster; 03.01.2020
comment
слово, которое я получаю от request.args.get(), я обновил свой вопрос, пожалуйста, посмотрите - person Codenewbie; 03.01.2020
comment
Ок привел пример. - person Belly Buster; 03.01.2020
comment
Все запуталось, так как я ищу здесь все слова длиной 6, но я запутался в word, о котором вы упомянули, если это просто word, я сделал это, но что, если я хочу искать все коллекции и получить все слова (каждая коллекция может иметь совпадение, поэтому я зацикливаю каждую коллекцию, получаю совпадение, которое является объектом курсора, если я не ошибаюсь, и добавляю каждый объект в список), почему я делаю это добавление, это все Я хочу отправить в шаблон как данные ...... Надеюсь, вы поняли это - person Codenewbie; 03.01.2020
comment
Могу ли я предложить вам начать еще один вопрос именно с вашей проблемы и цели. Это отклонилось от курса. Вам нужно свести это к проблеме и предоставить пример настройки данных, как это сделал я. Иначе никто не сможет помочь. - person Belly Buster; 03.01.2020
comment
У вас есть время, чтобы я мог объяснить вам в чате (10 минут или около того) - person Codenewbie; 03.01.2020
comment
Давайте продолжим обсуждение в чате. - person Codenewbie; 03.01.2020