protected override TQuery GetQuery(Expression expression)
        {
            Trace(expression, "Expression");

            // here we inject a special expression parser that fixes a few issues slated to be resolved in later releases of SC7
            IndexQuery rawQuery = new ExpressionParserWithSpatial(typeof(TElement), ItemType, FieldNameTranslator).Parse(expression);

            Trace(rawQuery, "Raw query:");
            IndexQuery optimizedQuery = QueryOptimizer.Optimize(rawQuery);

            Trace(optimizedQuery, "Optimized query:");
            TQuery mappedQuery = QueryMapper.MapQuery(optimizedQuery);

            return(mappedQuery);
        }
        public static async Task <ChangesFeedResponse <TSource> > QueryWithFilterAsync <TSource>(this IFlurlRequest request, CouchOptions options, ChangesFeedFilter filter,
                                                                                                 CancellationToken cancellationToken)
            where TSource : CouchDocument
        {
            if (filter is DocumentIdsChangesFeedFilter documentIdsFilter)
            {
                return(await request
                       .SetQueryParam("filter", "_doc_ids")
                       .PostJsonAsync(new ChangesFeedFilterDocuments(documentIdsFilter.Value), cancellationToken)
                       .ReceiveJson <ChangesFeedResponse <TSource> >()
                       .ConfigureAwait(false));
            }

            if (filter is SelectorChangesFeedFilter <TSource> selectorFilter)
            {
                MethodCallExpression whereExpression = Expression.Call(typeof(Queryable), nameof(Queryable.Where),
                                                                       new[] { typeof(TSource) }, Expression.Constant(Array.Empty <TSource>().AsQueryable()), selectorFilter.Value);

                var        optimizer      = new QueryOptimizer();
                Expression optimizedQuery = optimizer.Optimize(whereExpression);
                var        jsonSelector   = new QueryTranslator(options).Translate(optimizedQuery);
                return(await request
                       .WithHeader("Content-Type", "application/json")
                       .SetQueryParam("filter", "_selector")
                       .PostStringAsync(jsonSelector, cancellationToken)
                       .ReceiveJson <ChangesFeedResponse <TSource> >()
                       .ConfigureAwait(false));
            }

            if (filter is DesignChangesFeedFilter)
            {
                return(await request
                       .SetQueryParam("filter", "_design")
                       .GetJsonAsync <ChangesFeedResponse <TSource> >(cancellationToken)
                       .ConfigureAwait(false));
            }

            if (filter is ViewChangesFeedFilter viewFilter)
            {
                return(await request
                       .SetQueryParam("filter", "_view")
                       .SetQueryParam("view", viewFilter.Value)
                       .GetJsonAsync <ChangesFeedResponse <TSource> >(cancellationToken)
                       .ConfigureAwait(false));
            }
            throw new InvalidOperationException($"Filter of type {filter.GetType().Name} not supported.");
        }