Skip to content

Commit 584f4fd

Browse files
authored
Fix search + missing senses (#2006)
* Fix search + missing senses * Remove irrelevant distinct checks
1 parent 13cf941 commit 584f4fd

File tree

2 files changed

+87
-12
lines changed

2 files changed

+87
-12
lines changed

backend/FwLite/LcmCrdt/Data/MiniLcmRepository.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,20 @@ public async IAsyncEnumerable<Entry> GetEntries(
157157
string? query,
158158
FilterQueryOptions options)
159159
{
160+
if (options.Exemplar is not null)
161+
{
162+
var ws = (await GetWritingSystem(options.Exemplar.WritingSystem, WritingSystemType.Vernacular))?.WsId;
163+
if (ws is null)
164+
throw new NullReferenceException($"writing system {options.Exemplar.WritingSystem} not found");
165+
queryable = queryable.WhereExemplar(ws.Value, options.Exemplar.Value);
166+
}
167+
168+
if (options.Filter?.GridifyFilter != null)
169+
{
170+
// Do this BEFORE doing the FTS, which returns an expression that confuses the gridify query
171+
queryable = queryable.ApplyFiltering(options.Filter.GridifyFilter, config.Value.Mapper);
172+
}
173+
160174
bool sortingHandled = false;
161175
if (!string.IsNullOrEmpty(query))
162176
{
@@ -176,18 +190,6 @@ public async IAsyncEnumerable<Entry> GetEntries(
176190
}
177191
}
178192

179-
if (options.Exemplar is not null)
180-
{
181-
var ws = (await GetWritingSystem(options.Exemplar.WritingSystem, WritingSystemType.Vernacular))?.WsId;
182-
if (ws is null)
183-
throw new NullReferenceException($"writing system {options.Exemplar.WritingSystem} not found");
184-
queryable = queryable.WhereExemplar(ws.Value, options.Exemplar.Value);
185-
}
186-
187-
if (options.Filter?.GridifyFilter != null)
188-
{
189-
queryable = queryable.ApplyFiltering(options.Filter.GridifyFilter, config.Value.Mapper);
190-
}
191193
return (queryable, sortingHandled);
192194
}
193195

backend/FwLite/MiniLcm.Tests/QueryEntryTestsBase.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,27 @@ public async Task CanFilterToMissingSenses()
100100
results.Select(e => e.LexemeForm["en"]).Distinct().Should().BeEquivalentTo(Apple, Null_LexemeForm);
101101
}
102102

103+
[Fact]
104+
public async Task CanFilterToMissingSenses_AndSearch()
105+
{
106+
var results = await Api.SearchEntries(Apple, new(Filter: new() { GridifyFilter = "Senses=null" })).ToArrayAsync();
107+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Apple);
108+
}
109+
103110
[Fact]
104111
public async Task CanFilterToNotMissingSenses()
105112
{
106113
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses!=null" })).ToArrayAsync();
107114
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Kiwi, Peach, Banana);
108115
}
109116

117+
[Fact]
118+
public async Task CanFilterToNotMissingSenses_AndSearch()
119+
{
120+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses!=null" })).ToArrayAsync();
121+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
122+
}
123+
110124
[Fact]
111125
public async Task CanFilterToMissingPartOfSpeech()
112126
{
@@ -115,6 +129,14 @@ public async Task CanFilterToMissingPartOfSpeech()
115129
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
116130
}
117131

132+
[Fact]
133+
public async Task CanFilterToMissingPartOfSpeech_AndSearch()
134+
{
135+
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.PartOfSpeechId=" })).ToArrayAsync();
136+
//does not include entries with no senses
137+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
138+
}
139+
118140
[Fact]
119141
public async Task CanFilterToMissingExamples()
120142
{
@@ -124,13 +146,29 @@ public async Task CanFilterToMissingExamples()
124146
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach, Banana);
125147
}
126148

149+
[Fact]
150+
public async Task CanFilterToMissingExamples_AndSearch()
151+
{
152+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.ExampleSentences=null" })).ToArrayAsync();
153+
//Senses.ExampleSentences=null matches entries which have senses but no examples
154+
//it does not include Apple because it has no senses, to include it a filter Senses=null is needed
155+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
156+
}
157+
127158
[Fact]
128159
public async Task CanFilterToMissingSemanticDomains()
129160
{
130161
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses.SemanticDomains=null" })).ToArrayAsync();
131162
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
132163
}
133164

165+
[Fact]
166+
public async Task CanFilterToMissingSemanticDomains_AndSearch()
167+
{
168+
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.SemanticDomains=null" })).ToArrayAsync();
169+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
170+
}
171+
134172
[Fact]
135173
public async Task CanFilterToMissingSemanticDomainsWithEmptyArray()
136174
{
@@ -153,6 +191,13 @@ public async Task CanFilterToMissingComplexFormTypes()
153191
results.Select(e => e.LexemeForm["en"]).Distinct().Should().BeEquivalentTo(Apple, Banana, Kiwi, Null_LexemeForm);
154192
}
155193

194+
[Fact]
195+
public async Task CanFilterToMissingComplexFormTypes_AndSearch()
196+
{
197+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "ComplexFormTypes=null" })).ToArrayAsync();
198+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
199+
}
200+
156201
[Fact]
157202
public async Task CanFilterToMissingComplexFormTypesWithEmptyArray()
158203
{
@@ -189,6 +234,13 @@ public async Task CanFilterLexemeFormContains()
189234
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
190235
}
191236

237+
[Fact]
238+
public async Task CanFilterLexemeFormContains_AndSearch()
239+
{
240+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "LexemeForm[en]=*nan" })).ToArrayAsync();
241+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
242+
}
243+
192244
[Fact]
193245
public async Task CanFilterGlossNull()
194246
{
@@ -205,13 +257,27 @@ public async Task CanFilterGlossEmptyOrNull()
205257
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
206258
}
207259

260+
[Fact]
261+
public async Task CanFilterGlossEmptyOrNull_AndSearch()
262+
{
263+
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=" })).ToArrayAsync();
264+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
265+
}
266+
208267
[Fact]
209268
public async Task CanFilterGlossEqualsFruit()
210269
{
211270
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=Fruit" })).ToArrayAsync();
212271
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana, Kiwi);
213272
}
214273

274+
[Fact]
275+
public async Task CanFilterGlossEqualsFruit_AndSearch()
276+
{
277+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=Fruit" })).ToArrayAsync();
278+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
279+
}
280+
215281
[Fact]
216282
public async Task CanFilterLexemeContainsAAndNoComplexFormTypes()
217283
{
@@ -226,6 +292,13 @@ public async Task CanFilterExampleSentenceText()
226292
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
227293
}
228294

295+
[Fact]
296+
public async Task CanFilterExampleSentenceText_AndSearch()
297+
{
298+
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.ExampleSentences.Sentence[en]=*phone" })).ToArrayAsync();
299+
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
300+
}
301+
229302
[Fact]
230303
public async Task CanFilterToExampleSentenceWithMissingSentence()
231304
{

0 commit comments

Comments
 (0)