diff --git a/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs b/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs index e4aa597f2d7..68f9fd93f9b 100644 --- a/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs +++ b/src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs @@ -1371,6 +1371,7 @@ public static PipelineStageDefinition Search( renderedSearchDefinition.Add("index", searchOptions.IndexName, searchOptions.IndexName != null); renderedSearchDefinition.Add("returnStoredSource", searchOptions.ReturnStoredSource, searchOptions.ReturnStoredSource); renderedSearchDefinition.Add("scoreDetails", searchOptions.ScoreDetails, searchOptions.ScoreDetails); + renderedSearchDefinition.Add("tracking", () => searchOptions.Tracking.Render(), searchOptions.Tracking != null); var document = new BsonDocument(operatorName, renderedSearchDefinition); return new RenderedPipelineStageDefinition(operatorName, document, s); diff --git a/src/MongoDB.Driver/Search/SearchOptions.cs b/src/MongoDB.Driver/Search/SearchOptions.cs index 0c168372fe2..deea0780bdd 100644 --- a/src/MongoDB.Driver/Search/SearchOptions.cs +++ b/src/MongoDB.Driver/Search/SearchOptions.cs @@ -51,5 +51,10 @@ public sealed class SearchOptions /// Gets or sets the sort specification. /// public SortDefinition Sort { get; set; } + + /// + /// Gets or sets the options for tracking search terms. + /// + public SearchTrackingOptions Tracking { get; set; } } } diff --git a/src/MongoDB.Driver/Search/SearchTrackingOptions.cs b/src/MongoDB.Driver/Search/SearchTrackingOptions.cs new file mode 100644 index 00000000000..19c60c2afe8 --- /dev/null +++ b/src/MongoDB.Driver/Search/SearchTrackingOptions.cs @@ -0,0 +1,43 @@ +/* Copyright 2010-present MongoDB Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using MongoDB.Bson; +using MongoDB.Driver.Core.Misc; + +namespace MongoDB.Driver.Search +{ + /// + /// Options for tracking the search query. + /// + public sealed class SearchTrackingOptions + { + private string _searchTerms; + + /// + /// Text or term associated with the query to track. You can specify only one term per query. + /// + public string SearchTerms + { + get => _searchTerms; + set => _searchTerms = Ensure.IsNotNullOrEmpty(value, nameof(value)); + } + + internal BsonDocument Render() => + new() + { + { "searchTerms", _searchTerms, !string.IsNullOrEmpty(_searchTerms) } + }; + } +} diff --git a/tests/MongoDB.Driver.Tests/PipelineDefinitionBuilderTests.cs b/tests/MongoDB.Driver.Tests/PipelineDefinitionBuilderTests.cs index 7ba76a35f7b..b23f34df16a 100644 --- a/tests/MongoDB.Driver.Tests/PipelineDefinitionBuilderTests.cs +++ b/tests/MongoDB.Driver.Tests/PipelineDefinitionBuilderTests.cs @@ -207,6 +207,25 @@ public void Search_should_add_expected_stage_with_sort() stages[0].Should().Be("{ $search: { text: { query: 'foo', path: 'bar' }, sort: { 'foo': 1 } } }"); } + [Fact] + public void Search_should_add_expected_stage_with_tracking() + { + var pipeline = new EmptyPipelineDefinition(); + var builder = new SearchDefinitionBuilder(); + var searchOptions = new SearchOptions() + { + Tracking = new SearchTrackingOptions() + { + SearchTerms = "foo" + } + }; + + var result = pipeline.Search(builder.Text("bar", "foo"), searchOptions); + + var stages = RenderStages(result, BsonDocumentSerializer.Instance); + stages[0].Should().Be("{ $search: { text: { query: 'foo', path: 'bar' }, tracking: { searchTerms: 'foo' } } }"); + } + [Fact] public void Search_should_throw_when_pipeline_is_null() {