Skip to content

Commit 54a6818

Browse files
BorisDogDmitryLukyanov
authored andcommitted
CSHARP-4576: Atlas search: support score in Compound operator (#1045)
1 parent 7cbae1e commit 54a6818

File tree

5 files changed

+46
-13
lines changed

5 files changed

+46
-13
lines changed

src/MongoDB.Driver/Search/CompoundSearchDefinitionBuilder.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ public sealed class CompoundSearchDefinitionBuilder<TDocument>
2929
private List<SearchDefinition<TDocument>> _should;
3030
private List<SearchDefinition<TDocument>> _filter;
3131
private int _minimumShouldMatch = 0;
32+
private SearchScoreDefinition<TDocument> _score;
33+
34+
/// <summary>
35+
/// Initializes a new instance of the <see cref="CompoundSearchDefinitionBuilder{TDocument}"/> class.
36+
/// </summary>
37+
/// <param name="score"></param>
38+
public CompoundSearchDefinitionBuilder(SearchScoreDefinition<TDocument> score = null)
39+
{
40+
_score = score;
41+
}
3242

3343
/// <summary>
3444
/// Adds clauses which must match to produce results.
@@ -117,7 +127,7 @@ public CompoundSearchDefinitionBuilder<TDocument> MinimumShouldMatch(int minimum
117127
/// </summary>
118128
/// <returns>A compound search definition.</returns>
119129
public SearchDefinition<TDocument> ToSearchDefinition() =>
120-
new CompoundSearchDefinition<TDocument>(_must, _mustNot, _should, _filter, _minimumShouldMatch);
130+
new CompoundSearchDefinition<TDocument>(_must, _mustNot, _should, _filter, _minimumShouldMatch, _score);
121131

122132
/// <summary>
123133
/// Performs an implicit conversion from a <see cref="CompoundSearchDefinitionBuilder{TDocument}"/>

src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ public CompoundSearchDefinition(
6464
List<SearchDefinition<TDocument>> mustNot,
6565
List<SearchDefinition<TDocument>> should,
6666
List<SearchDefinition<TDocument>> filter,
67-
int minimumShouldMatch)
68-
: base(OperatorType.Compound)
67+
int minimumShouldMatch,
68+
SearchScoreDefinition<TDocument> score)
69+
: base(OperatorType.Compound, score)
6970
{
7071
// This constructor should always be called from the compound search definition builder that ensures the arguments are valid.
7172
_must = must;

src/MongoDB.Driver/Search/SearchDefinitionBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public SearchDefinition<TDocument> Autocomplete<TField>(
6868
/// Creates a builder for a compound search definition.
6969
/// </summary>
7070
/// <returns></returns>
71-
public CompoundSearchDefinitionBuilder<TDocument> Compound() => new CompoundSearchDefinitionBuilder<TDocument>();
71+
public CompoundSearchDefinitionBuilder<TDocument> Compound(SearchScoreDefinition<TDocument> score = null) => new CompoundSearchDefinitionBuilder<TDocument>(score);
7272

7373
/// <summary>
7474
/// Creates a search definition that queries for documents where an indexed field is equal

tests/MongoDB.Driver.Tests/Search/AtlasSearchTests.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,20 @@ public void Autocomplete()
8080
[Fact]
8181
public void Compound()
8282
{
83-
var result = SearchSingle(Builders.Search.Compound()
83+
const int score = 42;
84+
var searchDefinition = Builders.Search.Compound(Builders.SearchScore.Constant(score))
8485
.Must(Builders.Search.Text(x => x.Body, "life"), Builders.Search.Text(x => x.Body, "liberty"))
8586
.MustNot(Builders.Search.Text(x => x.Body, "property"))
86-
.Must(Builders.Search.Text(x => x.Body, "pursuit of happiness")));
87+
.Must(Builders.Search.Text(x => x.Body, "pursuit of happiness"));
8788

89+
var projectionDefinition = Builders.Projection
90+
.Include(x => x.Body)
91+
.Include(x => x.Title)
92+
.MetaSearchScore("score");
93+
94+
var result = SearchSingle(searchDefinition, projectionDefinition);
8895
result.Title.Should().Be("Declaration of Independence");
96+
result.Score.Should().Be(score);
8997
}
9098

9199
[Fact]
@@ -436,13 +444,17 @@ public void Wildcard()
436444
private List<AirbnbListing> GeoSearch(SearchDefinition<AirbnbListing> searchDefintion) =>
437445
GetGeoTestCollection().Aggregate().Search(searchDefintion).ToList();
438446

439-
private HistoricalDocument SearchSingle(SearchDefinition<HistoricalDocument> searchDefintion) =>
440-
GetTestCollection()
441-
.Aggregate()
442-
.Search(searchDefintion)
443-
.Limit(1)
444-
.ToList()
445-
.Single();
447+
private HistoricalDocument SearchSingle(SearchDefinition<HistoricalDocument> searchDefintion, ProjectionDefinition<HistoricalDocument, HistoricalDocument> projectionDefinition = null)
448+
{
449+
var fluent = GetTestCollection().Aggregate().Search(searchDefintion);
450+
451+
if (projectionDefinition != null)
452+
{
453+
fluent = fluent.Project(projectionDefinition);
454+
}
455+
456+
return fluent.Limit(1).ToList().Single();
457+
}
446458

447459
private IMongoCollection<HistoricalDocument> GetTestCollection() => _disposableMongoClient
448460
.GetDatabase("sample_training")

tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public void Compound()
157157
.Must(
158158
subject.Exists("z")),
159159
"{ compound: { must: [{ exists: { path: 'x' } }, { exists: { path: 'y' } }, { exists: { path: 'z' } }], mustNot: [{ exists: { path: 'foo' } }, { exists: { path: 'bar' } }] } }");
160+
161+
var scoreBuilder = new SearchScoreDefinitionBuilder<BsonDocument>();
162+
AssertRendered<BsonDocument>(
163+
subject.Compound(scoreBuilder.Constant(123)).Must(subject.Exists("x"), subject.Exists("y")),
164+
"{ compound: { must: [{ exists: { path: 'x' } }, { exists: { path: 'y' } } ], score: { constant: { value: 123 } } } }");
160165
}
161166

162167
[Fact]
@@ -175,6 +180,11 @@ public void Compound_typed()
175180
.Must(
176181
subject.Exists(p => p.LastName)),
177182
"{ compound: { must: [{ exists: { path: 'age' } }, { exists: { path: 'fn' } }, { exists: { path: 'ln' } }], mustNot: [{ exists: { path: 'ret' } }, { exists: { path: 'dob' } }] } }");
183+
184+
var scoreBuilder = new SearchScoreDefinitionBuilder<Person>();
185+
AssertRendered<Person>(
186+
subject.Compound(scoreBuilder.Constant(123)).Must(subject.Exists(p => p.Age)),
187+
"{ compound: { must: [{ exists: { path: 'age' } } ], score: { constant: { value: 123 } } } }");
178188
}
179189

180190
[Theory]

0 commit comments

Comments
 (0)