Пример #1
0
        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));
        }
Пример #2
0
        private async Task <object> ExecuteAsync(ElasticTranslateResult translation, CancellationToken cancellationToken = default(CancellationToken))
        {
            Log.Debug(null, null, "Executing query against document '{0}'", translation.SearchRequest.IndexType);

            try
            {
                ElasticResponse response;
                if (translation.SearchRequest.Query == ConstantCriteria.False)
                {
                    response = new ElasticResponse();
                }
                else
                {
                    response = await requestProcessor.SearchAsync(translation.SearchRequest, cancellationToken).ConfigureAwait(false);

                    if (response == null)
                    {
                        throw new InvalidOperationException("No HTTP response received.");
                    }
                }

                var result = translation.Materializer.Materialize(response);
                response.hits?.hits?.Clear(); // Clear list aggressively
                return(result);
            }
            catch (AggregateException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                return(null);  // Never called, as the above code re-throws
            }
        }
Пример #3
0
        /// <inheritdoc/>
        public async Task <object> ExecuteAsync(Expression expression, CancellationToken cancellationToken = default(CancellationToken))
        {
            Argument.EnsureNotNull("expression", expression);

            var translation = ElasticQueryTranslator.Translate(Mapping, expression);

            Log.Debug(null, null, "Executing query against document '{0}'", translation.SearchRequest.DocumentType);

            try
            {
                ElasticResponse response;
                if (translation.SearchRequest.Filter == ConstantCriteria.False)
                {
                    response = new ElasticResponse();
                }
                else
                {
                    response = await requestProcessor.SearchAsync(translation.SearchRequest, cancellationToken);

                    if (response == null)
                    {
                        throw new InvalidOperationException("No HTTP response received.");
                    }
                }

                return(translation.Materializer.Materialize(response));
            }
            catch (AggregateException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                return(null);  // Never called, as the above code re-throws
            }
        }
Пример #4
0
        public string ElasticResponseConstructor_OnValidInput_CreatesValidResponse()
        {
            var defaultResponse    = new ElasticResponse();
            var serializedResponse = JsonConvert.SerializeObject(defaultResponse);

            return(serializedResponse);
        }
        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));
            }
        }
Пример #6
0
        private object ExecuteInternal(Expression expression)
        {
            var translation = ElasticQueryTranslator.Translate(Mapping, Prefix, expression);
            var elementType = TypeHelper.GetSequenceElementType(expression.Type);

            Log.Debug(null, null, "Executing query against type {0}", elementType);

            try
            {
                ElasticResponse response;
                if (translation.SearchRequest.Filter == ConstantCriteria.False)
                {
                    response = new ElasticResponse();
                }
                else
                {
                    response = AsyncHelper.RunSync(() => requestProcessor.SearchAsync(translation.SearchRequest));
                    if (response == null)
                    {
                        throw new InvalidOperationException("No HTTP response received.");
                    }
                }

                return(translation.Materializer.Materialize(response));
            }
            catch (AggregateException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                return(null);  // Never called, as the above code re-throws
            }
        }
        public async Task <object> ExecuteAsync(Expression expression, CancellationToken cancellationToken = new CancellationToken())
        {
            var translation = ElasticQueryTranslator.Translate(this.Mapping, expression);

            try
            {
                ElasticResponse response;
                if (translation.SearchRequest.Filter == ConstantCriteria.False)
                {
                    response = new ElasticResponse();
                }
                else
                {
                    response = await this.requestProcessor.SearchAsync(translation.SearchRequest, cancellationToken);

                    if (response == null)
                    {
                        throw new InvalidOperationException("No HTTP response received.");
                    }
                }

                return(translation.Materializer.Materialize(response));
            }
            catch (AggregateException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                return(null);  // Never called, as the above code re-throws
            }
        }
Пример #8
0
 public ElasticResult <T[]> GetEntitiesFromElasticResponse <T>(ElasticResponse <T> response) where T : class
 {
     // If request bad executed.
     return(!response.Success
         ? ElasticResult <T[]> .FailResult(response.Message)
         : ElasticResult <T[]> .SuccessResult(
                response.Response.Hits.Select(h => h.Source).Where(s => s != null).ToArray()));
 }
Пример #9
0
        /// <summary>
        /// Determine whether at a given query response contains any hits.
        /// </summary>
        /// <param name="response">The <see cref="ElasticResponse"/> to check for emptiness.</param>
        /// <returns>true if the source sequence contains any elements; otherwise, false.</returns>
        public object Materialize(ElasticResponse response)
        {
            if (response.hits.total.value < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(response), "Contains a negative number of hits.");
            }

            return(response.hits.total.value > 0);
        }
        /// <summary>
        /// Determine whether at a given query response contains any Hits.
        /// </summary>
        /// <param name="response">The <see cref="ElasticResponse"/> to check for emptiness.</param>
        /// <returns>true if the source sequence contains any elements; otherwise, false.</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);
        }
        /// <summary>
        /// Materialize the result count for a given response.
        /// </summary>
        /// <param name="response">The <see cref="ElasticResponse"/> to obtain the count value from.</param>
        /// <returns>The result count expressed as either an int or long depending on the size of the count.</returns>
        public object Materialize(ElasticResponse response)
        {
            if (response.hits.total < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(response), "Contains a negative number of hits.");
            }

            return(Convert.ChangeType(response.hits.total, returnType));
        }
Пример #12
0
        /// <summary>
        /// Materialize the facets from an ElasticResponse into a List with a single CLR object as determined
        /// by the projector.
        /// </summary>
        /// <param name="response">ElasticResponse to obtain the facets from.</param>
        /// <returns>List containing a single CLR object with these facets projected onto them.</returns>
        public override object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            var element  = MaterializeSingle(response);
            var listType = typeof(List <>).MakeGenericType(ElementType);

            return(element == null
                ? Activator.CreateInstance(listType)
                : manyMethodInfo.MakeGenericMethod(ElementType).Invoke(null, new[] { element }));
        }
Пример #13
0
        public void CountMaterializerThrowsForNegativeCount()
        {
            var response = new ElasticResponse {
                hits = new Hits {
                    hits = new List <Hit>(), total = -1
                }
            };
            var materializer = new CountElasticMaterializer();

            Assert.Throws <ArgumentOutOfRangeException>(() => materializer.Materialize(response));
        }
Пример #14
0
        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));
        }
Пример #15
0
        public void ThenWillReturnEmptyListIfHitsIsNull()
        {
            //Arrange
            var response = new ElasticResponse <string>();

            //Act
            var responseItems = response.Items;

            //Assert
            responseItems.Should().NotBeNull();
            responseItems.Should().BeEmpty();
        }
Пример #16
0
        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);
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        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(typeof(int));

            var actual = materializer.Materialize(response);

            Assert.Equal(expected, actual);
        }
Пример #20
0
 internal static IEnumerable <string> GetResultSummary(ElasticResponse results)
 {
     if (results == null)
     {
         yield return("nothing");
     }
     else
     {
         if (results.hits?.hits != null && results.hits.hits.Count > 0)
         {
             yield return(results.hits.hits.Count + " hits");
         }
     }
 }
Пример #21
0
        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);
        }
Пример #22
0
        /// <summary>
        /// Materialize the result count for a given response.
        /// </summary>
        /// <param name="response">The <see cref="ElasticResponse"/> to obtain the count value from.</param>
        /// <returns>The ewaulr count expressed as either an int or long depending on the size of the count.</returns>
        public object Materialize(ElasticResponse response)
        {
            if (response.hits.total < 0)
            {
                throw new ArgumentOutOfRangeException("response", "Contains a negative number of hits.");
            }

            if (response.hits.total <= int.MaxValue)
            {
                return((int)response.hits.total);
            }

            return(response.hits.total);
        }
Пример #23
0
        public void CountMaterializerReturnsZeroCount()
        {
            const int expected = 0;
            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);
        }
Пример #24
0
        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();

            var actual = materializer.Materialize(response);

            Assert.Equal(expected, actual);
        }
Пример #25
0
        public object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            var hits = response.hits;

            if (hits == null || hits.hits == null || !hits.hits.Any())
            {
                return(Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)));
            }

            return(manyMethodInfo
                   .MakeGenericMethod(elementType)
                   .Invoke(null, new object[] { hits.hits, projector }));
        }
        /// <summary>
        /// Materialize the facets from an ElasticResponse into a List of CLR objects as determined
        /// by the projector.
        /// </summary>
        /// <param name="response">ElasticResponse to obtain the facets from.</param>
        /// <returns>List of CLR objects with these facets projected onto them.</returns>
        public object Materialize(ElasticResponse response)
        {
            Argument.EnsureNotNull("response", response);

            var facets = response.facets;

            if (facets == null || facets.Count == 0)
            {
                return(Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)));
            }

            return(manyMethodInfo
                   .MakeGenericMethod(elementType)
                   .Invoke(this, new object[] { response.facets }));
        }
        public void SimpleSelectProducesValidMaterializer()
        {
            var translation = ElasticQueryTranslator.Translate(Mapping, 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);
        }
Пример #28
0
        /// <inheritdoc/>
        public async Task <object> ExecuteAsync(Expression expression, CancellationToken cancellationToken = default(CancellationToken))
        {
            Argument.EnsureNotNull(nameof(expression), expression);

            var translation = ElasticQueryTranslator.Translate(Mapping, expression);

            Log.Debug(null, null, "Executing query against document '{0}'", translation.SearchRequest.DocumentType);

            try
            {
                ElasticResponse response;
                if (translation.SearchRequest.Filter == ConstantCriteria.False)
                {
                    response = new ElasticResponse();
                }
                else
                {
                    response = await requestProcessor.SearchAsync(translation.SearchRequest, cancellationToken);

                    if (response == null)
                    {
                        throw new InvalidOperationException("No HTTP response received.");
                    }
                }

                var result = translation.Materializer.Materialize(response);

                if (response.hits != null)
                {
                    var hits = response.hits.hits;
                    if (hits != null && hits.Capacity > 4096)
                    {
                        // If the response has a large number of hits then the List<T> instance might end up allocating an array on the large object heap.
                        // This means that the elements in that array can survive multiple rounds of garbage collection, even if they are not actually
                        // reachable anymore.
                        // Clearing out the collection after we materialized the result means the elements can be freed up.
                        hits.Clear();
                    }
                }

                return(result);
            }
            catch (AggregateException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                return(null);  // Never called, as the above code re-throws
            }
        }
        /// <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($"{prop.Name}_highlight", prop.Value);
                }
            }

            return(base.Materialize(response));
        }
Пример #30
0
        /// <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));
        }