有没有办法在名称中使用ElasticLowLevelClient.SearchAsync反序列化具有特殊字符的属性?

时间:2017-03-21 03:53:09

标签: elasticsearch-net

我有logstash将日志推送到elasticsearch,自动将@timestamp字段插入每个文档。我在此项目中使用了Elasticsearch.Net而不是NEST

每个文档看起来像:

{
  "Origin": 0,
  "VisitorId": "49f843eb-be38-4912-a3b8-277841cd709d",
  "CompanyId": 1,
  "ActivityType": 21,
  "Referer": "http://cn.bing.com/search?q=sogou&src=IE-SearchBox&FORM=IE10SR",
  "ProductId": 1,
  "version": "1.0",
  "Url": "http://localhost:8001/Product/Detail/1",
  "DeviceType": 1,
  "@timestamp": "2017-03-21T02:04:13.136Z",
  "UserId": 4,
  "host": "ZBL-PC",
  "@version": "1",
  "IpAddress": "14.197.145.136",
  "timestamp": "2017-03-21T02:04:13.136Z"
}

目前,我的搜索查询如下:

var res = client.SearchAsync<SearchResult<ProductVisit>>(index: _indexName,
    type: "viewsingleproduct",
    body: new PostData<object>(new
    {
      size = 10
    }));

public class ProductVisit
{
  public int? UserId { get; set; }
  public Guid? VisitorId { get; set; }
  public int DeviceType { get; set; }
  public string timestamp { get; set; }
  public int CompanyId { get; set; }
  public long ProductId { get; set; }
}

public class Hit<TDocument>
{
  public TDocument _source { get; set; }
}

public class Hits<TDocument>
{
  public int total { get; set; }
  public List<Hit<TDocument>> hits { get; set; }
}

public class SearchResult<TDocument>
{
  public Hits<TDocument> hits { get; set; }
}

检索文档的Elasticsearch.Net方法是声明一个DTO,它可以从响应中的json自动反序列化。但是,在这种情况下,我不能声明属性是有效的C#属性名称,以便可以填充@timestamp值。

在使用Newtonsoft.json的Nest中,我可以通过属性注释在elasticsearch中指定实际的字段名称(我记得JsonProperty将执行该技巧,并且NEST也有自己的属性,允许您指定财产名称)。但是,Elasticsearch.Net内部不使用Newtonsoft.json。它使用SimpleJson,它可以通过DataMember属性支持类似的技巧,但它需要启用SIMPLE_JSON_DATACONTRACT预处理器切换,默认情况下Elasticsearch.Net禁用它。

目前我的解决方案是将@timestamp字段复制到logstash配置中的timestamp,如上面的json doc所示。但这是一个黑客攻击。

我最初在请求方遇到问题,官方示例主要使用匿名类型构建查询:

new
{
  term = new
  {
    _TopicPostId = new {
      value = 4
    }
  }
},

但偶尔我需要构造包含特殊字符的字段名称的查询。我终于想通了我可以使用Dictionary而不是匿名类型而且它有效。例如:

new {
  range = new Dictionary<string, object>{{
    "@timestamp",
    new
    {
      gte = "now-1d/d",
      lte = "now/d"
    }
  }}
},

0 个答案:

没有答案