4

I'm currently looking at writing an ElasticSearch.Net/NEST client as a possible replacement for PlainElastic.Net (since ElasticSearch.Net has failover functionality I want to use)

In PlainElastic I can write something like:

var command = new SearchCommand(index, type);
var result = Connection.Post(command, query);
var searchResult = Serializer.ToSearchResult<T>(result);
return searchResult.Documents;

This will return an IEnumerable where each of the results are of type T. I want something similar in NEST and what I'm starting with as an initial test is:

var result = client.Search<T>("index", "type", query, null);

But I can't seem to find way to deserialize into results in the same way that PlainElastic.Net does using the ToSearchResult method. Does Elasticsearch.Net/NEST provide such way?

08/05/2015: Apologies badly worded question. What I was originally trying with NEST was the untyped version:

var result = client.Search("index", "type", query, null);

which was bringing back a result which I was trying to deserialize separately because the original attempt with the typed version:

var result = client.Search<T>("index", "type", query, null);

was throwing an exception:

System.NullReferenceException was unhandled by user code
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=Elasticsearch.Net
  StackTrace:
       at     Elasticsearch.Net.Serialization.PocoJsonSerializerStrategy.DeserializeObject(    Object value, Type type) in C:\code\elasticsearch-    net\src\Elasticsearch.Net\Serialization\SimpleJson.cs:line 1370
       at Elasticsearch.Net.Serialization.SimpleJson.DeserializeObject(String json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Serialization\SimpleJson.cs:line 553
   at Elasticsearch.Net.Serialization.SimpleJson.DeserializeObject[T](String json) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Serialization\SimpleJson.cs:line 570
   at Elasticsearch.Net.Serialization.ElasticsearchDefaultSerializer.Deserialize[T](Stream stream) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Serialization\ElasticsearchDefaultSerializer.cs:line 27
   at Elasticsearch.Net.Connection.RequestHandlers.RequestHandler.StreamToTypedResponse[T](ElasticsearchResponse`1 streamResponse, ITransportRequestState requestState, Byte[] readBytes) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\RequestHandlers\RequestHandler.cs:line 254
   at Elasticsearch.Net.Connection.RequestHandlers.RequestHandler.ReturnTypedResponse[T](TransportRequestState`1 requestState, ElasticsearchResponse`1 streamResponse, ElasticsearchServerError& error) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\RequestHandlers\RequestHandler.cs:line 106
   at Elasticsearch.Net.Connection.RequestHandlers.RequestHandler.CoordinateRequest[T](TransportRequestState`1 requestState, Int32 maxRetries, Int32 retried, Boolean& aliveResponse) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\RequestHandlers\RequestHandler.cs:line 131
   at Elasticsearch.Net.Connection.RequestHandlers.RequestHandler.DoRequest[T](TransportRequestState`1 requestState) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\RequestHandlers\RequestHandler.cs:line 177
   at Elasticsearch.Net.Connection.RequestHandlers.RequestHandler.Request[T](TransportRequestState`1 requestState, Object data) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\RequestHandlers\RequestHandler.cs:line 34
   at Elasticsearch.Net.Connection.Transport.DoRequest[T](String method, String path, Object data, IRequestParameters requestParameters) in C:\code\elasticsearch-net\src\Elasticsearch.Net\Connection\Transport.cs:line 343
   at Elasticsearch.Net.ElasticsearchClient.DoRequest[T](String method, String path, Object data, IRequestParameters requestParameters) in C:\code\elasticsearch-net\src\Elasticsearch.Net\ElasticsearchClient.cs:line 65
   at Elasticsearch.Net.ElasticsearchClient.Search[T](String index, String type, Object body, Func`2 requestParameters) in C:\code\elasticsearch-net\src\Elasticsearch.Net\ElasticsearchClient.Generated.cs:line 33515

Therefore I suppose my original question is still the same but more an attempt to understand why NEST does retrieve the results in the untyped version but fails to do the serialization in the type version.

Ben Franklin
  • 626
  • 6
  • 21

2 Answers2

8

The SearchResponse<T> has a Hits property (of type IEnumerable<IHit<T>> if I remember correctly).

Each hit then has a Source property, which is of type T.

So

var enumerable = results.Hits.Select(h => h.Source);

returns your IEnumerable<T>.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
samjudson
  • 56,243
  • 7
  • 59
  • 69
1

The response of your query will be a Nest.ISearchResponse<T>. By accessing the Documents property in the response you get an IEnumerable<T> which is the list of the results matching your search.

Update In order to respond in the updated question: T in var result = client.Search<T>("index", "type", query, null); should be the exact "type" that you include in your command and not the Generic T.

Manolis
  • 728
  • 8
  • 24