findBySearchTerm method
- required String searchTerm,
- required String searchField,
- required SearchTermType searchTermType,
- bool doSearchNumberEquivalent = false,
- int? limit,
Finds documents based on a given searchTerm
and searchField
.
The searchTermType
defines the type of field that is specified as searchField
. You are
able to search a SearchTermType.startsWith field for direct hits or for a SearchTermType.arrayContains
that may contain the searchField
.
This method returns raw data in the form of a List<Map<String, dynamic>>. If _tryAddLocalId
is
true then the map will also contain a local id field based on the _idFieldName
specified in the constructor so you may retrieve document id's more easily after serialization.
If you rather want to convert this data into a list of T
immediately you should use the
findBySearchTermWithConverter method instead. Make sure to have specified the _toJson
and _fromJson
methods or else the FirestoreApi will not know how to convert the data to T
.
Implementation
Future<FeedbackResponse<List<Map<String, dynamic>>>> findBySearchTerm({
required String searchTerm,
required String searchField,
required SearchTermType searchTermType,
bool doSearchNumberEquivalent = false,
int? limit,
}) async {
try {
_log.info(
message: 'Searching without converter..',
sensitiveData: _shouldNotSensitiveError
? null
: SensitiveData(
path: _collectionPath(),
searchTerm: searchTerm,
searchField: searchField,
searchTermType: searchTermType,
limit: limit,
),
);
collectionReferenceQuery(
Query<Map<String, dynamic>> collectionReference) =>
searchTermType.isArray
? limit == null
? collectionReference.where(
searchField,
arrayContainsAny: [searchTerm, ...searchTerm.split(' ')],
)
: collectionReference.where(
searchField,
arrayContainsAny: [searchTerm, ...searchTerm.split(' ')],
).limit(limit)
: limit == null
? collectionReference.where(
searchField,
isGreaterThanOrEqualTo: searchTerm,
isLessThan: '$searchTerm\uf8ff',
)
: collectionReference
.where(
searchField,
isGreaterThanOrEqualTo: searchTerm,
isLessThan: '$searchTerm\uf8ff',
)
.limit(limit);
final result = (await collectionReferenceQuery(
findCollection(),
).get(_getOptions))
.docs
.map(
(e) => e.data(),
)
.toList();
if (doSearchNumberEquivalent) {
try {
final numberSearchTerm = double.tryParse(searchTerm);
if (numberSearchTerm != null) {
collectionReferenceQuery(
Query<Map<String, dynamic>> collectionReference) =>
searchTermType.isArray
? limit == null
? collectionReference.where(
searchField,
arrayContainsAny: [numberSearchTerm],
)
: collectionReference.where(
searchField,
arrayContainsAny: [numberSearchTerm],
).limit(limit)
: limit == null
? collectionReference.where(
searchField,
isGreaterThanOrEqualTo: numberSearchTerm,
isLessThan: numberSearchTerm + 1,
)
: collectionReference
.where(
searchField,
isGreaterThanOrEqualTo: numberSearchTerm,
isLessThan: numberSearchTerm + 1,
)
.limit(limit);
final numberResult = (await collectionReferenceQuery(
findCollection(),
).get(_getOptions))
.docs
.map(
(e) => e.data(),
)
.toList();
result.addAll(numberResult);
}
} catch (error, stackTrace) {
_log.error(
message:
'${error.runtimeType} caught while trying to search for number equivalent',
sensitiveData: _shouldNotSensitiveError
? null
: SensitiveData(
path: _collectionPath(),
searchTerm: searchTerm,
searchTermType: searchTermType,
searchField: searchField,
),
error: error,
stackTrace: stackTrace,
);
}
}
_logResultLength(result);
return _responseConfig.searchSuccessResponse(
isPlural: result.isPlural,
result: result,
);
} catch (error, stackTrace) {
_log.error(
message: 'Unable to find documents',
sensitiveData: _shouldNotSensitiveError
? null
: SensitiveData(
path: _collectionPath(),
searchTerm: searchTerm,
searchField: searchField,
searchTermType: searchTermType,
),
error: error,
stackTrace: stackTrace,
);
return _responseConfig.searchFailedResponse(isPlural: true);
}
}