Couchbase Lite Xamarin: Is there a limit of nested AND conditions in queries?

Hello, I see this (caught) exception in logs since I started implementing a complex query that has 14 nested “AND” conditions as it’s filtering on days of the week (2 weeks from now)

Couchbase.Lite.CouchbaseLiteException: CouchbaseLiteException (LiteCoreDomain / 23): JSON parse error: JSON error: LEVELS_EXCEEDED

The stacktrace does not provide much helpful information:

LiteCore.Interop
NativeHandler.ThrowOrHandle ()
LiteCore.Interop
NativeHandler.Execute (LiteCore.Interop.C4TryLogicDelegate1 block)
LiteCore
LiteCoreBridge.Check (LiteCore.Interop.C4TryLogicDelegate1 block)
Couchbase.Lite.Support
ThreadSafety.DoLockedBridge (LiteCore.Interop.C4TryLogicDelegate1 a)
Couchbase.Lite.Internal.Query
XQuery.Check ()
Couchbase.Lite.Internal.Query
XQuery+<>c__DisplayClass75_0.<Execute>b__0 (LiteCore.Interop.C4Error* err)
LiteCore.Interop
NativeHandler.Execute (LiteCore.Interop.C4TryLogicDelegate2 block)
LiteCore
LiteCoreBridge.Check (LiteCore.Interop.C4TryLogicDelegate2 block)
Couchbase.Lite.Support
ThreadSafety.DoLockedBridge (LiteCore.Interop.C4TryLogicDelegate2 a)
Couchbase.Lite.Internal.Query
XQuery.Execute ()

Code snippet:

    {
        var whereQueryExpression = Expression.Property("type").EqualTo(Expression.String("work"));
        if (dates.Count() > 0)
        {
            IExpression innerQueryExpression = Expression.Property("StartDate").EqualTo(Expression.String(dates[0]));
            innerQueryExpression = innerQueryExpression.Or(Expression.Property("FinishDate").EqualTo(Expression.String(dates[0])));
            foreach (string date in dates)
            {
                innerQueryExpression = innerQueryExpression.Or(Expression.Property("StartDate").EqualTo(Expression.String(date)));
                innerQueryExpression = innerQueryExpression.Or(Expression.Property("FinishDate").EqualTo(Expression.String(date)));
            }
            whereQueryExpression = whereQueryExpression.And(innerQueryExpression);
        }
        var query = new DisposableQuery();
        query.Query = QueryBuilder.Select(SelectWithId(withId))
            .From(DataSource.Database(GetDatabaseInstance(database)))
                           .Where(whereQueryExpression)
                           .OrderBy(Ordering.Property("StartDate").Ascending())
                           .Limit(Expression.Int(limit), Expression.Int(offset));
        return query;
    }

Thank you

This has come up once before … the JSON parser used in Couchbase Lite Core has a fixed maximum nesting depth (50, I think) for performance reasons. Your query is translating into a JSON form that exceeds that, probably because the dates array is longer than forty-something elements.

Ideally the query translator in CBL should concatenate multiple OR expressions into a single longer one, but I guess it doesn’t.

You should be able to work around this by using an IN expression with the list of dates on the right-hand side. I don’t remember for certain whether CBL supports IN expressions; LiteCore does.

1 Like