搜索带有日期范围的工单字段

Search the fields of tickets with date range

我有以下型号

public class Ticket
{
    public string Id { get; set; }

    public string Question { get; set; }

    public DateTime CreateDate { get; set; }

    public DateTime ClosedDate { get; set; }

    public int Votes { get; set; }
}

我正在使用 ElasticSearch Nest 客户端搜索任何字段包含日期范围内特定文本的工单。

我尝试了以下方法:

        var result = client.Search<Ticket>(
            s => s.Query(q => 
                            q.Bool(b => 
                                b.Must(ms => ms.QueryString(qs => qs.Query(term)))
                                 .Filter(f => 
                                         f.Bool(bb => 
                                                bb.Must(ms => ms.DateRange(dr => dr.GreaterThanOrEquals(from).LessThanOrEquals(to))
            ))))));

它returns所有门票不分时间指定。

它也只搜索完整的单词,而我想在文本中搜索单词的任何部分。

有什么想法吗?

DateRange 查询需要 Elasticsearch 中字段的 Field 值才能 运行 反对。当没有为此提供值时,NEST 认为查询是无条件的,并且不会将其序列化为发送的查询的一部分。

例如给定

var term = "term";
var to = DateTime.Now;
var from = to.AddDays(-7);

您当前的查询序列化为

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ]
    }
  }
}

如果添加Field

var result = client.Search<Ticket>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(ms => ms
                .QueryString(qs => qs
                    .Query(term)
                )
            )
            .Filter(f => f
                .Bool(bb => bb
                    .Must(ms => ms
                        .DateRange(dr => dr
                            .Field(df => df.CreateDate)
                            .GreaterThanOrEquals(from)
                            .LessThanOrEquals(to)
                        )
                    )
                )
            )
        )
    )
);

现在序列化为

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ],
      "filter": [
        {
          "bool": {
            "must": [
              {
                "range": {
                  "createDate": {
                    "gte": "2018-07-17T12:20:02.8659934+10:00",
                    "lte": "2018-07-24T12:20:02.8659934+10:00"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

使用operator overloading on queries,这样可以写得更简洁

var result = client.Search<Ticket>(s => s
    .Query(q => q
        .QueryString(qs => qs
                .Query(term)
        ) && +q
        .DateRange(dr => dr
            .Field(df => df.CreateDate)
            .GreaterThanOrEquals(from)
            .LessThanOrEquals(to)
        )
    )
);

序列化为

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "term"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "createDate": {
              "gte": "2018-07-17T12:21:50.2175114+10:00",
              "lte": "2018-07-24T12:21:50.2175114+10:00"
            }
          }
        }
      ]
    }
  }
}