/// <summary>
        /// Create a facet query parameter
        /// </summary>
        /// <param name="documentSearch">Document search engine</param>
        /// <param name="aliasName">Name of alias added in query</param>
        /// <param name="query">Query used to make facet</param>
        /// <param name="instance">Instance of facet ready to configure</param>
        /// <returns>Document search engine</returns>
        public static DocumentSearch <TDocument> FacetQuery <TDocument>(this DocumentSearch <TDocument> documentSearch, string aliasName, Action <SearchQuery <TDocument> > query, Action <IFacetQueryParameter <TDocument> > instance = null)
            where TDocument : Document
        {
            Checker.IsNull(query);

            var parameter = documentSearch.ServiceProvider.GetService <IFacetQueryParameter <TDocument> >();

            parameter.AliasName(aliasName);
            var search = documentSearch.ServiceProvider.GetService <SearchQuery <TDocument> >();

            query.Invoke(search);
            parameter.Query(search);

            instance?.Invoke(parameter);

            documentSearch.Add(parameter);

            // ReSharper disable once InvertIf
            if (!documentSearch.Contains <IFacetsResult <TDocument> >())
            {
                var facetsResult = documentSearch.ServiceProvider.GetService <IFacetsResult <TDocument> >();
                documentSearch.Add(facetsResult);
            }

            return(documentSearch);
        }
        /// <summary>
        /// Create a facet field parameter
        /// </summary>
        /// <param name="documentSearch">Document search engine</param>
        /// <param name="fieldExpression">Expression used to find field name</param>
        /// <param name="instance">Instance of facet ready to configure</param>
        /// <returns>Document search engine</returns>
        public static DocumentSearch <TDocument> FacetField <TDocument>(this DocumentSearch <TDocument> documentSearch, Expression <Func <TDocument, object> > fieldExpression, Action <IFacetFieldParameter <TDocument> > instance = null)
            where TDocument : Document
        {
            Checker.IsNull(fieldExpression);

            var parameter = documentSearch.ServiceProvider.GetService <IFacetFieldParameter <TDocument> >();

            parameter.FieldExpression(fieldExpression);

            instance?.Invoke(parameter);

            documentSearch.Add(parameter);

            // ReSharper disable once InvertIf
            if (!documentSearch.Contains <IFacetsResult <TDocument> >())
            {
                var facetsResult = documentSearch.ServiceProvider.GetService <IFacetsResult <TDocument> >();
                documentSearch.Add(facetsResult);
            }

            return(documentSearch);
        }
        /// <summary>
        /// Create a facet range parameter
        /// </summary>
        /// <param name="documentSearch">Document search engine</param>
        /// <param name="aliasName">Name of alias added in query</param>
        /// <param name="fieldExpression">Expression used to find field name</param>
        /// <param name="centerPoint">Center point to spatial filter</param>
        /// <param name="distance">Distance from center point</param>
        /// <param name="instance">Instance of parameter ready to configure</param>
        /// <returns>Document search engine</returns>
        public static DocumentSearch <TDocument> FacetSpatial <TDocument>(this DocumentSearch <TDocument> documentSearch, string aliasName, Expression <Func <TDocument, object> > fieldExpression, GeoCoordinate centerPoint, decimal distance, Action <IFacetSpatialParameter <TDocument> > instance = null)
            where TDocument : Document
        {
            var parameter = documentSearch.ServiceProvider.GetService <IFacetSpatialParameter <TDocument> >();

            parameter.AliasName(aliasName);
            parameter.FieldExpression(fieldExpression);
            parameter.CenterPoint(centerPoint);
            parameter.Distance(distance);

            instance?.Invoke(parameter);

            documentSearch.Add(parameter);

            // ReSharper disable once InvertIf
            if (!documentSearch.Contains <IFacetsResult <TDocument> >())
            {
                var facetsResult = documentSearch.ServiceProvider.GetService <IFacetsResult <TDocument> >();
                documentSearch.Add(facetsResult);
            }

            return(documentSearch);
        }
        /// <summary>
        /// Create a facet range parameter
        /// </summary>
        /// <param name="documentSearch">Document search engine</param>
        /// <param name="aliasName">Name of alias added in query</param>
        /// <param name="fieldExpression">Expression used to find field name</param>
        /// <param name="gap">Size of each range bucket to make facet</param>
        /// <param name="start">Lower bound to make facet</param>
        /// <param name="end">Upper bound to make facet</param>
        /// <param name="instance">Instance of parameter ready to configure</param>
        /// <returns>Document search engine</returns>
        public static DocumentSearch <TDocument> FacetRange <TDocument>(this DocumentSearch <TDocument> documentSearch, string aliasName, Expression <Func <TDocument, object> > fieldExpression, string gap, string start, string end, Action <IFacetRangeParameter <TDocument> > instance = null)
            where TDocument : Document
        {
            var parameter = documentSearch.ServiceProvider.GetService <IFacetRangeParameter <TDocument> >();

            parameter.AliasName(aliasName);
            parameter.FieldExpression(fieldExpression);
            parameter.Gap(gap);
            parameter.Start(start);
            parameter.End(end);

            instance?.Invoke(parameter);

            documentSearch.Add(parameter);

            // ReSharper disable once InvertIf
            if (!documentSearch.Contains <IFacetsResult <TDocument> >())
            {
                var facetsResult = documentSearch.ServiceProvider.GetService <IFacetsResult <TDocument> >();
                documentSearch.Add(facetsResult);
            }

            return(documentSearch);
        }