findBySearchTerm method

Future<FeedbackResponse<List<Map<String, dynamic>>>> findBySearchTerm({
  1. required String searchTerm,
  2. required String searchField,
  3. required SearchTermType searchTermType,
  4. bool doSearchNumberEquivalent = false,
  5. 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);
  }
}