/// <summary>
        /// Materialize whether at least one result exists for a given ElasticResponse.
        /// </summary>
        /// <param name="response">ElasticResponse to obtain the existence of a result.</param>
        /// <returns>The existence expressed as a boolean.  If count is 0, false.  Otherwise true</returns>
        public object Materialize(ElasticResponse response)
        {
            if (response.hits.total < 0)
                throw new ArgumentOutOfRangeException("response", "Contains a negative number of hits.");

            return response.hits.total > 0;
        }
        public void CountMaterializerThrowsForNegativeCount()
        {
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = -1 } };
            var materializer = new CountElasticMaterializer(typeof(int));

            Assert.Throws<ArgumentOutOfRangeException>(() => materializer.Materialize(response));
        }
        public void ThrowsWhenNegativeHits()
        {
            const int total = -1;
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = total } };
            var materializer = new AnyElasticMaterializer();

            Assert.Throws<ArgumentOutOfRangeException>(() => materializer.Materialize(response));
        }
        public void ReturnsTrueWhenOneOrMoreHits(int total)
        {
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = total } };
            var materializer = new AnyElasticMaterializer();

            var actual = materializer.Materialize(response);

            Assert.Equal(true, actual);
        }
        public void ReturnsFalseWhenNoHits()
        {
            const int total = 0;
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = total } };
            var materializer = new AnyElasticMaterializer();

            var actual = materializer.Materialize(response);

            Assert.Equal(false, actual);
        }
        public void CountMaterializerReturnsIntCount()
        {
            const int expected = int.MaxValue;
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = expected } };
            var materializer = new CountElasticMaterializer();

            var actual = materializer.Materialize(response);

            Assert.Equal(expected, actual);
        }
        public void SimpleSelectProducesValidMaterializer()
        {
            var translation = ElasticQueryTranslator.Translate(Mapping, "prefix", Robots.Expression);
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>() } };

            Assert.NotNull(translation.Materializer);
            var materialized = translation.Materializer.Materialize(response);
            Assert.IsAssignableFrom<IEnumerable<Robot>>(materialized);
            Assert.Empty((IEnumerable<Robot>)materialized);
        }
        public void MaterializeWithNoFacetsReturnsBlankList()
        {
            var materializer = new ListTermlessFacetsElasticMaterializer(r => r, typeof(SampleClass), typeof(string));
            var response = new ElasticResponse { facets = new JObject() };

            var actual = materializer.Materialize(response);

            var actualList = Assert.IsType<List<SampleClass>>(actual);
            Assert.Empty(actualList);
        }
        public void CountMaterializerReturnsLongCount()
        {
            const long expected = (long)int.MaxValue + 1;
            var response = new ElasticResponse { hits = new Hits { hits = new List<Hit>(), total = expected } };
            var materializer = new CountElasticMaterializer(typeof(long));

            var actual = materializer.Materialize(response);

            Assert.Equal(expected, actual);
        }
        public void MaterializeReturnsEmptyListWhenHitsHitsAreEmpty()
        {
            var materializer = new ListHitsElasticMaterializer(MaterializerTestHelper.ItemCreator, typeof(SampleClass));
            var response = new ElasticResponse { hits = null };

            var materialized = materializer.Materialize(response);

            var materializedList = Assert.IsType<List<SampleClass>>(materialized);
            Assert.Empty(materializedList);
        }
        /// <summary>
        /// Add to response fields that needs to read highlighted info.
        /// </summary>
        /// <param name="response">ElasticResponse to obtain the existence of a result.</param>
        /// <returns>Return result of next materializer</returns>
        public override object Materialize(ElasticResponse response)
        {
            foreach (var hit in response.hits.hits)
            {
                if (hit.highlight == null) continue;
                foreach (var prop in hit.highlight.Properties())
                {
                    hit._source.Add(string.Format("{0}_highlight", prop.Name), prop.Value);
                }
            }

            return base.Materialize(response);
        }
        static IEnumerable<string> GetResultSummary(ElasticResponse results)
        {
            if (results == null)
            {
                yield return "nothing";
            }
            else
            {
                if (results.hits != null && results.hits.hits != null && results.hits.hits.Count > 0)
                    yield return results.hits.hits.Count + " hits";

                if (results.facets != null && results.facets.Count > 0)
                    yield return results.facets.Count + " facets";
            }
        }
        /// <summary>
        /// Materialize a single object from the response using the <see cref="projector"/>
        /// or return null if there are no applicable facets.
        /// </summary>
        /// <param name="response">The <see cref="ElasticResponse"/> to materialize facets from.</param>
        /// <returns>Object materialized from the response using the projector or null if no corresponding facets.</returns>
        public object MaterializeSingle(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            var facets = response.facets;
            if (facets == null || facets.Count <= 0) return null;

            var facetsWithoutTerms = facets
                .Values()
                .Where(x => termlessFacetTypes.Contains(x["_type"].ToString()))
                .ToList();

            return facetsWithoutTerms.Any()
                ? projector(new AggregateStatisticalRow(key, facets))
                : null;
        }
        public object Materialize(ElasticResponse response)
        {
            var enumerator = response.hits.hits.GetEnumerator();

            if (!enumerator.MoveNext())
                if (defaultIfNone)
                    return elementType.IsValueType ? Activator.CreateInstance(elementType) : null;
                else
                    throw new InvalidOperationException("Sequence contains no elements");

            var current = enumerator.Current;

            if (throwIfMoreThanOne && enumerator.MoveNext())
                throw new InvalidOperationException("Sequence contains more than one element");

            return itemCreator(current);
        }
        public object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            using (var enumerator = response.hits.hits.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                    if (defaultIfNone)
                        return TypeHelper.CreateDefault(elementType);
                    else
                        throw new InvalidOperationException("Sequence contains no elements");

                var current = enumerator.Current;

                if (throwIfMoreThanOne && enumerator.MoveNext())
                    throw new InvalidOperationException("Sequence contains more than one element");

                return projector(current);
            }
        }
        /// <summary>
        /// Process response, then translate it to next materializer.
        /// </summary>
        /// <param name="response">ElasticResponse to obtain the existence of a result.</param>
        /// <returns>Return result of previous materializer, previously processed by self</returns>
        public virtual object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("Next materializer must be setted.",Next);

            return Next.Materialize(response);
        }
        /// <summary>
        /// Materialize a single CLR object from the ElasticResponse using the projector or
        /// return a default value based on the element type.
        /// </summary>
        /// <param name="response">ElasticResponse received from Elasticsearch.</param>
        /// <returns>CLR object materialized from the response using the projector or default if no corresponding facets.</returns>
        public virtual object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            return MaterializeSingle(response) ?? TypeHelper.CreateDefault(elementType);
        }