Skip doesn't work in CBLite view?

I’m working with Couchbase Server 4.5.0 community edition and Couchbase Mobile 1.4.0 with the Android SDK.

I have a view that allow me to find all documents of a specific type:

private View getCouchbaseFindAllView(Database database) {
        View view = database.getView(FIND_ALL_VIEW_NAME);
        if (view.getMap() == null) {
            Mapper map = new Mapper() {
                @Override
                public void map(Map<String, Object> document, Emitter emitter) {
                    if (isDocumentValid(document, isMetaData(), null);)
                        emitter.emit(document.get(DOCUMENT_TYPE_FIELD), null);
                }
            };
            Reducer reducer = new Reducer() {
                @Override
                public Object reduce(List<Object> keys, List<Object> values, boolean rereduce) {
                    if (rereduce)
                        return com.couchbase.lite.View.totalValues(values);
                    else
                        return values.size();
                }
            };
            view.setMapReduce(map, reducer, FIND_ALL_VIEW_VERSION);
        }
        return view;
    } 

And I run a query this way:

protected List<TData> findAll(Database database, Integer limit, Integer skip) {
	View findAllView = getCouchbaseFindAllView(database);
	Query query = findAllView.createQuery();
	if(skip != null)
		query.setSkip(skip);
	if(limit != null)
		query.setLimit(limit);
	query.setMapOnly(true);
	query.setKeys(new ArrayList<Object>(){{add(getDataType());}});
	
	QueryEnumerator rows = query.run();
	List<TData> result = new ArrayList<>();

	for (; rows.hasNext(); ) {
		QueryRow row = rows.next();
		result.add(propertiesToData(row.getDocument().getProperties()));
	}
	
	return result;
}

And here is how I try to do pagination:

//Limit is to avoid to get an OOM error by getting too much patients from the database.
int nbItemsPerPage = 100;
int limit = nbItemsPerPage;
int skip = 0;

List<Patient> patients = couchbase.patientManager().findAll(false, false, null, limit, skip);

while (patients != null && !patients.isEmpty() && nbPatientsDuplicated < totalPatientsToDuplicate) {
    startDuplication(nbOccurrences, duplicator, patients);
    skip = limit;
    limit += nbItemsPerPage;
    if(limit > totalPatientsToDuplicate)
        limit = xFirsts;
    if(skip >= limit)
        break;
    patients = couchbase.patientManager().findAll(false, false, null, limit, skip);
}

But it seems that the skip property is not taken into account because the first time I run the query I receive 100 patients but the 2nd time I receive 200 (so I have a total of 300 patients but I should have a total of 200). Is their something wrong with the way I’m trying to achieve pagination? Or is their a known bug with the skip parameter that I should be aware of?

Inside the function “startDuplication” I’m inserting new patients inside the database, maybe it’s important to mention it.

Assuming “limit” is the number of elements to fetch, then shouldn’t that be nbItemsPerPage always?

What Priya said — you should be incrementing skip, not limit, in the loop.

Well thank’s. I was assuming that limit was the first x documents so if I have a limit of 1000 and skip of 500 it will take the 1000 first but skip 500 of them -> result = 500 doc. But I was totally wrong. Thank you for your help!

1 Like