如何使用 NEST for ElasticSearch 在范围过滤器中映射时间戳参数?

问题描述 投票:0回答:2

尝试使用时间戳字段按范围过滤数据。查询如下:

        var scanResults = await _elasticClient.SearchAsync<OemCatalogModel>(s => s.Index(indexName)
                .Source(sf => sf
                    .Includes(i => i
                        .Fields(
                                    f => f.Event,
                                    f => f.MemberId,
                                    f => f.IsInternalUser,
                                    f => f.IndexName,
                                    f => f.IsMobile,
                                    f => f.VinNumber,
                                    f => f.Timestamp
                        )
                    )
                )
                .Query(q => q.Range(p => p.Field<Timestamp>(t=>t.Timestamp)
                             .GreaterThanOrEquals(sd)
                             .LessThanOrEquals(ed)
                    ))
                .Size(10000).Scroll("60s"));

startDate
endDate
从 DatePicker 获取为 DateTimeOffset 并初始化
sd
ed
,如下所示:

        var sd = startDate.Value.ToUnixTimeSeconds();
        var ed = endDate.Value.ToUnixTimeSeconds();

时间戳字段在映射模型中看起来如下

    [Date(Name = "timestamp")]
    public Int64 Timestamp { get; set; }

此查询引发了“parse_exception”异常:

    "reason" : {
      "type" : "parse_exception",
      "reason" : "failed to parse date field [1.6540308E9] with format [epoch_second]: [failed to parse date field [1.6540308E9] with format [epoch_second]]",
      "caused_by" : {
        "type" : "illegal_argument_exception",
        "reason" : "failed to parse date field [1.6540308E9] with format [epoch_second]",
        "caused_by" : {
          "type" : "date_time_parse_exception",
          "reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
        }
      }
    }

NEST 生成的 ElasticSearch 查询如下所示:

{“查询”:{“范围”:{“时间戳”:{“gte”:1654030800.0,“lte”:1654203599.0}}},“大小”:10000,“_source”:{“包括”:[ "事件","member_id","is_internal_user","indexName","is_mobile","vin_number","时间戳"]}}

此过滤器不起作用,因为添加了范围参数

.0
。我检查了这个,没有
.0
,它是有效的。例如
_source
的结果如下所示:

    "_source" : {
      "member_id" : 69500,
      "is_mobile" : false,
      "event" : "close_unit_card",
      "is_internal_user" : false,
      "timestamp" : 1654066236
    }

如何使用时间戳正确映射范围过滤器?也许我必须使用

DataRange
?如果是,如何将
sd
ed
转换为 ElasticSearch 中使用的时间戳?

还尝试执行以下操作,但出现不同的异常:

查询如下:

.Query(q => q.DateRange(p => p.Field(t=>t.Timestamp)
.GreaterThanOrEquals(DateTime.Parse(startDate.Value.ToString()))
.LessThanOrEquals(DateTime.Parse(endDate.Value.ToString()))))

出现以下异常:

"reason" : {
          "type" : "parse_exception",
          "reason" : "failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]: [failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]]",
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]",
            "caused_by" : {
              "type" : "date_time_parse_exception",
              "reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
            }
          }
        }
c# elasticsearch timestamp nest date-range
2个回答
1
投票

奇怪的解决方案但有效:

初始化开始和结束日期:

    var sd = startDate.Value.ToUnixTimeSeconds();
    var ed = endDate.Value.ToUnixTimeSeconds();

日期范围看起来像:

.Query(q => q.DateRange(p => p.Field(t=>t.Timestamp).Format("epoch_second")
                                 .GreaterThanOrEquals(sd)
                                 .LessThanOrEquals(ed)
                                 ))

模型看起来像:

    [Date(Format = DateFormat.epoch_second, Name = "timestamp")]
    public DateTime Timestamp { get; set; }

0
投票

通过 DateRange,您可以使用 DateTime 结构:

var searchResponse = client.Search<_Source>(s => s
    .Query(q => q
        .Bool(b => b
            .Filter(fi => fi
                .DateRange(r => r
                    .Field(f => f.timestamp) // Replace with your actual timestamp field
                    .GreaterThanOrEquals(new DateTime(2023, 11, 17, 12, 05, 0)) // Start time
                    .LessThanOrEquals(new DateTime(2023, 11, 17, 12, 10, 0)) // End time
                )
            )
            .Must(fi => fi
                .Term(t => t
                    .Field(f => f.host.name) // Replace with your actual host name field
                    .Value("evp-lwsj101")
                )
            )
         )
    )
    .From(0)
    .Size(100) // adjust the size based on your needs
);
© www.soinside.com 2019 - 2024. All rights reserved.