【问题标题】:Any way to get NEST to deserialise directly into results?有什么方法可以让 NEST 直接反序列化为结果?
【发布时间】:2015-05-10 04:18:50
【问题描述】:

我目前正在考虑编写一个 ElasticSearch.Net/NEST 客户端作为 PlainElastic.Net 的可能替代品(因为 ElasticSearch.Net 具有我想使用的故障转移功能)

在 PlainElastic 中我可以这样写:

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

这将返回一个 IEnumerable,其中每个结果都是 T 类型。 我想要在 NEST 中使用类似的东西,而我作为初始测试的开始是:

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

但我似乎无法像 PlainElastic.Net 使用 ToSearchResult 方法那样找到反序列化结果的方法。 Elasticsearch.Net/NEST 是否提供这种方式?

2015 年 8 月 5 日: 对措辞不当的问题表示歉意。我最初尝试使用 NEST 的是无类型版本:

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

这带来了一个我试图单独反序列化的结果,因为最初尝试使用类型化版本:

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

抛出异常:

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

因此,我想我最初的问题仍然相同,但更多的是试图理解为什么 NEST 确实检索了无类型版本中的结果,但未能在类型版本中进行序列化。

【问题讨论】:

    标签: elasticsearch nest plainelastic.net


    【解决方案1】:

    SearchResponse&lt;T&gt; 有一个 Hits 属性(如果我没记错的话,它的类型是 IEnumberable&lt;IHit&lt;T&gt;&gt;。)。

    然后每个命中都有一个 Source 属性,它的类型为 T。

    所以

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

    给你你的IEnumerable&lt;T&gt;

    【讨论】:

    • 就我而言,h.Source 始终为空。我在 Fields 字典中得到了一个 id(例如 userId),仅此而已。
    • 您是否需要任何字段?如果您这样做,则不会返回源。
    • 确实,后来我想通了,这就是问题所在。当我删除字段定义时,一切正常。无论如何谢谢:)
    • 然后您可以在IEnumerable&lt;T&gt; 上致电.ToList()。谢谢! :)
    【解决方案2】:

    您的查询回复将是Nest.ISearchResponse&lt;T&gt;。通过访问响应中的 Documents 属性,您将获得一个 IEnumerable&lt;T&gt;,它是与您的搜索匹配的结果列表。

    更新 为了回答更新后的问题:var result = client.Search&lt;T&gt;("index", "type", query, null); 中的 T 应该是您在命令中包含的确切 "type",而不是通用 T。

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多