results method
Executes a search and returns a stream of individual term results, unsorted and unfiltered.
Implementation
Stream<TermSearchResult<T>> results() {
final FullTextSearch<T> search = this;
final Set<String> terms = search.term
.toString()
.split(searchTermTokenizer)
.where((_) => _ != '')
.toSet();
Stream<TokenizedItem<T>> tokens = (search.items).map((item) {
final tokens = search.tokenize(item).map((t) {
if (t == null) return null;
if (t is FTSToken) {
return t;
} else {
return FTSToken('$t');
}
}).notNullSet();
return TokenizedItem(tokens, item);
});
Stream<TermSearchResult<T>> matches =
tokens.expand((TokenizedItem<T> item) {
// Creates a cross-product of tokens and terms
Iterable<TermMatch> matching = item.tokens.expand((token) {
return terms.expand((_term) {
for (final matcher in matchers) {
final matches = matcher.apply(this, item, _term, token);
if (matches.isNotEmpty) {
return matches;
}
}
return const [];
});
});
if (matching.isEmpty) return [];
final matchedTerms =
matching.map((TermMatch match) => match.term).toSet();
final matchedTokens = matching.toSet();
final termResult = TermSearchResult(
item.result,
matchedTerms,
matchedTokens,
matchedTerms.length >= terms.length,
);
log.fine('Scorers: $scorers');
search.scorers.forEach(
(scorer) => scorer.scoreTerm(search, termResult, termResult.score));
termResult.scoreValue;
return [termResult];
});
return matches;
}