From bbf52c7a8eb6a6751de1511bc423af75ecba8f80 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Tue, 14 Apr 2026 10:44:32 +0200 Subject: [PATCH] Changes API: Use content_last_updated instead of last_updated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Changes API now queries and sorts by content_last_updated so that metadata-only changes (nav reordering, mapping rollovers) no longer surface in the feed. The API response shape is unchanged — lastUpdated is still the JSON field name — keeping this non-breaking for consumers. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Changes/ChangesUsecase.cs | 2 +- .../Changes/IChangesGateway.cs | 2 +- .../Elastic.Documentation.Search/ChangesGateway.cs | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/Elastic.Documentation.Api.Core/Changes/ChangesUsecase.cs b/src/api/Elastic.Documentation.Api.Core/Changes/ChangesUsecase.cs index 7a444a1dd..fac3706e6 100644 --- a/src/api/Elastic.Documentation.Api.Core/Changes/ChangesUsecase.cs +++ b/src/api/Elastic.Documentation.Api.Core/Changes/ChangesUsecase.cs @@ -82,7 +82,7 @@ private static string EncodeCursor(ChangesPageCursor cursor) var buffer = new ArrayBufferWriter(); using var writer = new Utf8JsonWriter(buffer); writer.WriteStartArray(); - writer.WriteNumberValue(cursor.LastUpdatedEpochMs); + writer.WriteNumberValue(cursor.ContentLastUpdatedEpochMs); writer.WriteStringValue(cursor.Url); writer.WriteEndArray(); writer.Flush(); diff --git a/src/api/Elastic.Documentation.Api.Core/Changes/IChangesGateway.cs b/src/api/Elastic.Documentation.Api.Core/Changes/IChangesGateway.cs index 72c921351..27a02fe31 100644 --- a/src/api/Elastic.Documentation.Api.Core/Changes/IChangesGateway.cs +++ b/src/api/Elastic.Documentation.Api.Core/Changes/IChangesGateway.cs @@ -26,7 +26,7 @@ public record ChangesResult } /// Cursor for search_after pagination over changed pages. -public record ChangesPageCursor(long LastUpdatedEpochMs, string Url); +public record ChangesPageCursor(long ContentLastUpdatedEpochMs, string Url); /// Shared defaults for the changes feed. public static class ChangesDefaults diff --git a/src/services/Elastic.Documentation.Search/ChangesGateway.cs b/src/services/Elastic.Documentation.Search/ChangesGateway.cs index ecd4b3576..d1715ba42 100644 --- a/src/services/Elastic.Documentation.Search/ChangesGateway.cs +++ b/src/services/Elastic.Documentation.Search/ChangesGateway.cs @@ -11,7 +11,7 @@ namespace Elastic.Documentation.Search; /// /// Elasticsearch gateway for the documentation changes feed. -/// Queries last_updated > since with search_after cursor pagination. +/// Queries content_last_updated > since with search_after cursor pagination. /// Uses a shared Point In Time (PIT) for consistent pagination across requests. /// public partial class ChangesGateway( @@ -67,12 +67,12 @@ await clientAccessor.Client.SearchAsync(s => .Pit(p => p.Id(pitId).KeepAlive(SharedPointInTimeManager.PitKeepAlive)) .Query(q => q.Range(r => r .Date(dr => dr - .Field(f => f.LastUpdated) + .Field(f => f.ContentLastUpdated) .Gt(request.Since.ToString("O")) ) )) .Sort( - so => so.Field(f => f.LastUpdated, sf => sf.Order(SortOrder.Asc)), + so => so.Field(f => f.ContentLastUpdated, sf => sf.Order(SortOrder.Asc)), so => so.Field(f => f.Url, sf => sf.Order(SortOrder.Asc)) ) .Source(sf => sf @@ -82,7 +82,7 @@ await clientAccessor.Client.SearchAsync(s => e => e.Title, e => e.SearchTitle, e => e.Type, - e => e.LastUpdated + e => e.ContentLastUpdated ) ) ); @@ -90,7 +90,7 @@ await clientAccessor.Client.SearchAsync(s => if (request.Cursor is { } cursor) { _ = s.SearchAfter( - FieldValue.Long(cursor.LastUpdatedEpochMs), + FieldValue.Long(cursor.ContentLastUpdatedEpochMs), FieldValue.String(cursor.Url) ); } @@ -116,7 +116,7 @@ private static ChangesResult BuildResult(SearchResponse r { Url = doc.Url, Title = doc.Title, - LastUpdated = doc.LastUpdated + LastUpdated = doc.ContentLastUpdated }; }) .ToList();