使用 PIT(时间点)ID 和 Search_After API -NEST ElasticSearch

Mar*_*kCo 2 c# console-application elasticsearch nest elasticsearch-dsl

我一直在阅读Point in time API,并希望在我的.net 应用程序中使用 NEST 来实现它。然而,在阅读那篇文章(.net 应用程序超链接)时,我看到了如下所示的 Fluent DSL 示例。有没有一种方法可以找到该 ID,而无需转到控制台上的 kibana 并进行查询搜索来获取 id,然后将该 id 放入“a-point-in-time-id”中?或者“a-point-in-time-id”是否会为您执行此操作,就像映射到 ID 一样?

s => s
.PointInTime("a-point-in-time-id", p => p
.KeepAlive("1m"))
Run Code Online (Sandbox Code Playgroud)

我知道在 kibana cli 控制台中如果您这样做:

POST /app-logs*/_pit?keep_alive=5m它会给你一个 PIT(时间点)ID。你如何在 NEST 中检索它?

当阅读search_after并尝试使用 Fluent DSL 示例在 .net 客户端使用后的搜索来实现它时。我注意到他们有“项目”一词,但没有说明示例中的“项目”是什么。那到底是什么?

s => s
.Sort(srt => srt
    .Descending(p => p.NumberOfCommits)
    .Descending(p => p.Name)
)
.SearchAfter(
    Project.First.NumberOfCommits,
    Project.First.Name
)
Run Code Online (Sandbox Code Playgroud)

在这里,我尝试实现.PointInTime()and .Sort().SearchAfter()但卡住了。

var response = await _elasticClient.SearchAsync<Source>(s => s
                  .Size(3000) // must see about this
                  .Source(src => src.Includes(i => i
                                    .Fields(f => f.timestamp,
                                            fields => fields.messageTemplate,
                                            fields => fields.message)))
                  .Index("app-logs*"
                  .Query(q => +q
                      .DateRange(dr => dr
                          .Field("@timestamp")
                              .GreaterThanOrEquals("2021-06-12T16:39:32.727-05:00")
                              .LessThanOrEquals(DateTime.Now))))
                  .PointInTime("", p => p
                                   .KeepAlive("5m"))
                  .Sort(srt => srt
                               .Ascending(p => p.timestamp))
                  .SearchAfter()
Run Code Online (Sandbox Code Playgroud)

我知道当您使用 PIT ID 时,您不需要在搜索中使用索引,但在超链接示例中,它没有显示您将如何实现该索引。所以只是有点不知道如何做到这一点。任何指示/指导/教程都会很棒!


但只是想看看我如何在 NEST 中做到这一点,但如果你说它是 XPACK 的一部分,我会理解。

小智 6

我能够将 PIT 和 SearchAfter 与下面的代码示例结合起来:

var pit = string.IsNullOrEmpty(pitId) ? client.OpenPointInTime(new OpenPointInTimeDescriptor().KeepAlive(ServerDetail.TTL).Index(Indices.Index(Name))) : null;

            var request = new SearchRequest(Name)
            {
                SearchAfter = string.IsNullOrEmpty(pitId) ? null : new string[] { last },
                Size = ServerDetail.PageSize,
                PointInTime = new PointInTime(pit == null ? pitId : pit.Id)
            };
 List<FieldSort> sorts = new List<FieldSort>();
            foreach (var item in sortBy)
            {
                sorts.Add(new FieldSort() { Field = item.Field, Order = item.Direction == SortDirection.Asc ? SortOrder.Ascending : SortOrder.Descending });
            }
            request.Sort = sorts.ToArray();
Run Code Online (Sandbox Code Playgroud)

您的 SearchAfter 值应该是上一个搜索结果的最后一个对象的排序字段中的值。

对于第一个搜索,pitId 为 null,因此创建一个新的,对于后续请求,将传递pitId。

希望这对你有用吗?