Problem with a query on Android

java
query

#1

Hi,
I need help with a query i use in java (Android):

The database is like this:

{
  "YEAR": 2017,
  "CAUS": "",
  "NMBH": "xxxxxxxxx",
  "NAME": "xxxxxxx",
  "OFF": "First Road 1",
  "FULLTIME": "xxxxxx",
  "FUNCTION": "xxxxxxxx",
  "OFFADDR": "xxxxxxx",
  "MATR": "123456",
  "MONTH": "11",
  "QUAL": "xxxxxx",
  "TDES": "xxxxxxx",
  "UCOD": 1324132,
  "UFFAPPL": "xxxxx",
  "UNITAPROD": "xxxxxxxx",
  "id": "1324234",
  "t_ter_REG": "xxxxxxxx,
  "_rev": "1-cd2be12c983d43228d2d641da9a30f6b",
  "_id": "0061167"}

Here is the query:

Query query = QueryBuilder
                            .select(SelectResult.all())
                            .from(DataSource.database(database))
                            .where(Expression.property("OFF").equalTo(Expression.string("First Road 1")))
                            .orderBy(Ordering.property("NAME").ascending())
                            .limit(Expression.intValue(25));
                    ResultSet rs = null;
                    try {
                        rs = query.execute();
                    } catch (CouchbaseLiteException e) {
                        e.printStackTrace();
                    }
                    for (Result result : rs) {
                        int a=0;
                        a=a+1;
                        Log.e("Sample", String.format("%s", result.getString(a)));
                        android.util.Log.e(TAG, String.format("%s", result.toMap()));

                    }

I don’t get any result in the log, and I tried several times.
The fields are all indexed, and the databse syncs: I tried using an document ID (writing directly) and it works perfectly.
The only thing I obtain from the debugger is:

I/Sync: statusChanged() c4Status -> C4ReplicatorStatus{activityLevel=4, progressUnitsCompleted=412, progressUnitsTotal=412, progressDocumentCount=1, errorDomain=1, errorCode=26, errorInternalInfo=1000}
I/Sync: C4ReplicatorListener.statusChanged() status -> C4ReplicatorStatus{activityLevel=3, progressUnitsCompleted=412, progressUnitsTotal=412, progressDocumentCount=1, errorDomain=1, errorCode=26, errorInternalInfo=1001}
I/Sync: Replicator[<*> Database@38449ae{name='iscritti'} URLEndpoint{url=ws://192.168.50.160:4984/iscritti}] is busy, progress 412/412, error: CouchbaseLiteException{domain='CouchbaseLite', code=26, msg=Document update conflict}
I/Sync: statusChanged() c4Status -> C4ReplicatorStatus{activityLevel=3, progressUnitsCompleted=412, progressUnitsTotal=412, progressDocumentCount=1, errorDomain=0, errorCode=0, errorInternalInfo=0}
I/Sync: Replicator[<*> Database@38449ae{name='iscritti'} URLEndpoint{url=ws://192.168.50.160:4984/iscritti}] is idle, progress 412/412, error: null
I/Sync: statusChanged() c4Status -> C4ReplicatorStatus{activityLevel=3, progressUnitsCompleted=412, progressUnitsTotal=412, progressDocumentCount=1, errorDomain=1, errorCode=26, errorInternalInfo=1001}
I/Sync: Replicator[<*> Database@38449ae{name='iscritti'} URLEndpoint{url=ws://192.168.50.160:4984/iscritti}] is idle, progress 412/412, error: CouchbaseLiteException{domain='CouchbaseLite', code=26, msg=Document update conflict}
E/Replication Comp Log: Schedular Completed
E/ert: Error code:: 26

What is the error 26? I couldn’t find the description in the documentation.
Thank you for the help.


#2

The query looks OK. But it looks like your document JSON came from Sync Gateway. Are you sure those documents exist in CBL too? Are you sure you ran the query after the replicator downloaded documents?

The error looks like a revision conflict with a doc on the server (see the logs).


#3

Hi,
below you can see my Couchbase server. I have the documents on the server indexed and I can search them.

I waited for the replicator to finish before sending the query, and I set the replicator to Continuous:

ReplicatorConfiguration config = new ReplicatorConfiguration(database, new URLEndpoint(url));
        config.setReplicatorType(ReplicatorConfiguration.ReplicatorType.PUSH_AND_PULL);
        config.setContinuous(true);
        config.setAuthenticator(new BasicAuthenticator("luigi", "Rubisco1"));

        Replicator replicator = new Replicator(config);
        replicator.addChangeListener(new ReplicatorChangeListener() {
            @Override
            public void changed(ReplicatorChange change) {

                if (change.getReplicator().getStatus().getActivityLevel().equals(Replicator.ActivityLevel.IDLE)) {

                    Log.i("Replication Comp Log", "Schedular Completed");

                }
                if (change.getReplicator().getStatus().getActivityLevel().equals(Replicator.ActivityLevel.STOPPED) || change.getReplicator().getStatus().getActivityLevel().equals(Replicator.ActivityLevel.OFFLINE)) {
                    // stopReplication();
                    Log.i("Rep schedular  Log", "ReplicationTag Stopped");
                }
            }
        });
        replicator.start();

        Database.setLogLevel(LogDomain.REPLICATOR, LogLevel.VERBOSE);
        replicator.addChangeListener(new ReplicatorChangeListener() {
            @Override
            public void changed(ReplicatorChange change) {
                if (change.getStatus().getActivityLevel() == Replicator.ActivityLevel.STOPPED)
                    com.couchbase.lite.internal.support.Log.i(TAG, "Replication stopped");
            }
        });
        replicator.addChangeListener(new ReplicatorChangeListener() {
            @Override
            public void changed(ReplicatorChange change) {
                CouchbaseLiteException error = change.getStatus().getError();
                if (error != null)
                    com.couchbase.lite.internal.support.Log.e(TAG, "Error code:: %d", error.getCode());
            }
        });

I think I have a problem with the query that have as results a map:
If I make this (below) I get the right answer.

Query query = QueryBuilder.select(SelectResult.all())
                 .SelectResult.property("name"),
                .from(DataSource.database(database))
                .where(Expression.property("NAME").equalTo(Expression.string("John Doe")));
try {
                        rs = query.execute();
                    } catch (CouchbaseLiteException e) {
                        e.printStackTrace();
                    }
                    for (Result result : rs) {
                        int a=0;
                        a=a+1;
                        android.util.Log.e(TAG, result.getString("id"));
                        //there is only one John Doe

                    }

I still have no idea about the problem. (there is no error on the server logs)

Thank you


#4

The output of the result of select all is a dictionary containing all the user defined keys. It is not a flat result as you are trying to use it. So first get result.getDictionary(0) before attempting to access keys (note that ID is not part of the Select all)


#5

So, should I do something similar to this?:

Query query = QueryBuilder
                            .select(SelectResult.all())
                            //.select(SelectResult.expression(Meta.id),
                            //        SelectResult.property("OFFADDR"),
                            //        SelectResult.property("NAME"))  
                            .from(DataSource.database(database))
                            .where(Expression.property("OFFADDR").equalTo(Expression.string("theaddress")))
                            .orderBy(Ordering.property("NAME").ascending())
                            .limit(Expression.intValue(3));
                    ResultSet rs = null;
                    try {
                        rs = query.execute();
                        Log.i("TEST QUERY", "query done");

                    } catch (CouchbaseLiteException e) {
                        e.printStackTrace();
                        Log.e("TEST QUERY", "query not done");
                    }
                    for (Result result : rs) {
                        Dictionary all = result.getDictionary(0);
                        Log.i("Sample", String.format("Iscritti id -> %s", all.getString("_id")));
                        Log.e("Sample", String.format("Iscritti name -> %s", all.getString("NAME")));
//
                    }
                }
            });

Thank you very much for the help


#6

Yes, that is what I am saying (except that ‘_id’ will not be there, as I mentioned. That must be selected separately as it is a meta property)