Как получить все документы в базе данных CouchDB, не вызывая нехватки памяти

У меня есть база данных coucdb, которая содержит около 200 000 твитов, ключи — это идентификатор твита. У меня есть запрос, который должен получить все документы для поиска некоторой информации. Я использую lightcouch для работы с CouchDB в веб-приложении Java. Если я создам dbClient следующим образом:

List<JsonObject>tweets = dbClient.view("_all_docs").query(JsonObject.class);

а затем прокручивайте твиты, для каждого JsonObject в твитах используйте

JsonObject tweetJson = dbClient.find(JsonObject.class, tweet.get("id").toString().replaceAll("\"", ""));

чтобы получить каждый твит по одному, потребовалось очень много времени для 200000 документов. Если я загружаю все документы в один запрос, используя includeDocs (true)

List<JsonObject>allTweets = dbClient.view("_all_docs").includeDocs(true).query(JsonObject.class);

это вызвало исключение нехватки памяти, поскольку количество документов слишком велико. Итак, как я могу справиться с этой проблемой? Я думаю об использовании limit(5000) для извлечения 5000 документов каждый раз и перебора всей базы данных, но я не знаю, как написать цикл, чтобы продолжать извлекать следующие 5000 после первых 5000 документов. Одним из возможных решений является использование startKey и endKey, но я не понимаю, как их использовать, когда ключ является идентификатором твита.


person keduadoi    schedule 11.09.2014    source источник
comment
Используйте 1_. См.: lightcouch.org/lightcouch-guide.html#pagination.   -  person ssnobody    schedule 11.09.2014
comment
Как использовать страницу запроса? Вот что я сделал: Page‹JsonObject› page = dbClient.view(_all_docs).queryPage(5000,null,JsonObject.class); а затем цикл while: while(page.isHasNext()){...} но он выдает ошибку: Ожидаемая строка, но был Begin_object   -  person keduadoi    schedule 11.09.2014
comment
Я не использовал его сам, но github.com/daumproject/daum-extra/blob/master/ содержит пример кода в функции testPagination, который использует queryPage и isHasNext, который может быть полезен.   -  person ssnobody    schedule 11.09.2014


Ответы (1)


Используйте queryPage, но обязательно используйте строку в качестве ключа См.: https://github.com/lightcouch/LightCouch/issues/26#event-122327174

0.1.6 по-прежнему показывает такое поведение.

Обходной путь, который я нашел для этого, выглядит примерно так:

    changes = DbClient.changes()
            .since(null) // or... since(since) if you want an offset
            .includeDocs(true);


    int size = 1;
    getCursor("0");
    while (size > 0 ) {  
        ChangesResult resultSet = changes.limit(40000).getChanges();
        List<ChangesResult.Row> rowList = resultSet.getResults();
        for (ChangesResult.Row feed: rowList) {
            <instantiate your object via gson>
        .
        .
        .
        }
        getCursor(resultSet.getLastSeq());
        size = rowList.size();
    }
person Max Robbertze    schedule 25.03.2015