Skip to content

Commit a86c1ab

Browse files
committed
Include name matching in every query (that is on the first page).
1 parent d6346c7 commit a86c1ab

File tree

7 files changed

+48
-12
lines changed

7 files changed

+48
-12
lines changed

app/lib/search/mem_index.dart

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,20 @@ class InMemoryPackageIndex {
153153
}
154154

155155
// do text matching
156-
final textResults = _searchText(packages, query.parsedQuery.text);
156+
final parsedQueryText = query.parsedQuery.text;
157+
final textResults = _searchText(
158+
packages,
159+
parsedQueryText,
160+
includeNameMatches: (query.offset ?? 0) == 0,
161+
);
157162

158163
// filter packages that doesn't match text query
159164
if (textResults != null) {
160165
final keys = textResults.pkgScore.getKeys();
161166
packages.removeWhere((x) => !keys.contains(x));
162167
}
163168

164-
List<String>? nameMatches;
169+
final nameMatches = textResults?.nameMatches;
165170
List<PackageHit> packageHits;
166171
switch (query.effectiveOrder ?? SearchOrder.top) {
167172
case SearchOrder.top:
@@ -175,12 +180,6 @@ class InMemoryPackageIndex {
175180
/// multiplication outcomes.
176181
final overallScore = textResults.pkgScore
177182
.map((key, value) => value * _adjustedOverallScores[key]!);
178-
// If the search hits have an exact name match, we move it to the front of the result list.
179-
final parsedQueryText = query.parsedQuery.text;
180-
if (parsedQueryText != null &&
181-
_documentsByName.containsKey(parsedQueryText)) {
182-
nameMatches = <String>[parsedQueryText];
183-
}
184183
packageHits = _rankWithValues(overallScore.getValues());
185184
break;
186185
case SearchOrder.text:
@@ -242,12 +241,16 @@ class InMemoryPackageIndex {
242241
}
243242
}
244243

245-
_TextResults? _searchText(Set<String> packages, String? text) {
244+
_TextResults? _searchText(
245+
Set<String> packages,
246+
String? text, {
247+
required bool includeNameMatches,
248+
}) {
246249
final sw = Stopwatch()..start();
247250
if (text != null && text.isNotEmpty) {
248251
final words = splitForQuery(text);
249252
if (words.isEmpty) {
250-
return _TextResults(Score.empty(), {});
253+
return _TextResults.empty();
251254
}
252255

253256
bool aborted = false;
@@ -261,6 +264,12 @@ class InMemoryPackageIndex {
261264
return aborted;
262265
}
263266

267+
Set<String>? nameMatches;
268+
if (includeNameMatches && _documentsByName.containsKey(text)) {
269+
nameMatches ??= <String>{};
270+
nameMatches.add(text);
271+
}
272+
264273
// Multiple words are scored separately, and then the individual scores
265274
// are multiplied. We can use a package filter that is applied after each
266275
// word to reduce the scope of the later words based on the previous results.
@@ -272,6 +281,11 @@ class InMemoryPackageIndex {
272281
for (final word in words) {
273282
final nameScore =
274283
_packageNameIndex.searchWord(word, packages: wordScopedPackages);
284+
if (includeNameMatches && _documentsByName.containsKey(word)) {
285+
nameMatches ??= <String>{};
286+
nameMatches.add(word);
287+
}
288+
275289
final descr = _descrIndex
276290
.searchWords([word], weight: 0.90, limitToIds: wordScopedPackages);
277291
final readme = _readmeIndex
@@ -343,7 +357,11 @@ class InMemoryPackageIndex {
343357
score = Score(matched);
344358
}
345359

346-
return _TextResults(score, topApiPages);
360+
return _TextResults(
361+
score,
362+
topApiPages,
363+
nameMatches: nameMatches?.toList(),
364+
);
347365
}
348366
return null;
349367
}
@@ -423,8 +441,19 @@ class InMemoryPackageIndex {
423441
class _TextResults {
424442
final Score pkgScore;
425443
final Map<String, List<MapEntry<String, double>>> topApiPages;
444+
final List<String>? nameMatches;
445+
446+
factory _TextResults.empty() => _TextResults(
447+
Score.empty(),
448+
{},
449+
nameMatches: null,
450+
);
426451

427-
_TextResults(this.pkgScore, this.topApiPages);
452+
_TextResults(
453+
this.pkgScore,
454+
this.topApiPages, {
455+
required this.nameMatches,
456+
});
428457
}
429458

430459
/// A simple (non-inverted) index designed for package name lookup.

app/test/search/angular_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void main() {
3737
expect(json.decode(json.encode(result)), {
3838
'timestamp': isNotNull,
3939
'totalCount': 2,
40+
'nameMatches': ['angular'],
4041
'sdkLibraryHits': [],
4142
'packageHits': [
4243
{'package': 'angular', 'score': 1.0},

app/test/search/api_doc_page_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void main() {
5353
expect(json.decode(json.encode(result)), {
5454
'timestamp': isNotNull,
5555
'totalCount': 2,
56+
'nameMatches': ['foo'],
5657
'sdkLibraryHits': [],
5758
'packageHits': [
5859
{'package': 'foo', 'score': 1.0}, // finds package name

app/test/search/haversine_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ MIT'''),
380380
expect(json.decode(json.encode(result)), {
381381
'timestamp': isNotNull,
382382
'totalCount': 3,
383+
'nameMatches': ['haversine'],
383384
'sdkLibraryHits': [],
384385
'packageHits': [
385386
{'package': 'haversine', 'score': 1.0},

app/test/search/maps_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void main() {
2626
expect(json.decode(json.encode(result)), {
2727
'timestamp': isNotNull,
2828
'totalCount': 2,
29+
'nameMatches': ['maps'],
2930
'sdkLibraryHits': [],
3031
'packageHits': [
3132
{'package': 'maps', 'score': 1.0},
@@ -40,6 +41,7 @@ void main() {
4041
expect(json.decode(json.encode(result)), {
4142
'timestamp': isNotNull,
4243
'totalCount': 2,
44+
'nameMatches': ['map'],
4345
'sdkLibraryHits': [],
4446
'packageHits': [
4547
{'package': 'maps', 'score': 1.0},

app/test/search/mem_index_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ server.dart adds a small, prescriptive server (PicoServer) that can be configure
250250
expect(json.decode(json.encode(result)), {
251251
'timestamp': isNotNull,
252252
'totalCount': 2,
253+
'nameMatches': ['http'],
253254
'sdkLibraryHits': [],
254255
'packageHits': [
255256
{'package': 'http'},

app/test/search/travis_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
5555
expect(json.decode(json.encode(result)), {
5656
'timestamp': isNotNull,
5757
'totalCount': 1,
58+
'nameMatches': ['travis'],
5859
'sdkLibraryHits': [],
5960
'packageHits': [
6061
{'package': 'travis', 'score': 1.0},

0 commit comments

Comments
 (0)