Skip to content

Filtering with Partial Matches in algoliasearch #15

@reiko-dev

Description

@reiko-dev

Hello guys, first, thanks for this amazing library!

I'm exploring options for filtering search results in Algolia using wildcards within the algoliasearch library. My goal is to achieve an effect similar to prefix searches, where a search term like name:"3A*" would return records where the name attribute starts with "3A" (e.g., "3A AUTOMOVEIS").

Current Understanding:

Filters with wildcards in algoliasearch are primarily designed for prefix searches.
Searching using the query parameter allows for wildcards to potentially match partial terms within searchable attributes.

Exploration so Far:

Using facetFilters for name:
I attempted using facetFilters with a wildcard (name:"3A*") for the name attribute. However, this approach returns nothing.

Desired Behavior:

I'd like to be able to search for and filter results based on partial matches within specific attributes (e.g., name, cnpj).

Questions and Options:

Is there a recommended approach for achieving partial match filtering using algoliasearch?
If not, what are the best alternatives for this scenario (considering options like faceting, search queries, or potential configuration adjustments)?

Current code:

const indexName = 'companies_name_manager_socialreason_cnpj';

const restrictSearchableAttributes = [
  'name',
  'cnpj',
  'socialReason',
  'managers',
];

void main() async {
  final client = SearchClient(appId: algoliaID, apiKey: algoliaAPIKey);

  await client.setSettings(
    indexName: indexName,
    indexSettings: IndexSettings(
      queryType: QueryType.prefixLast,
      searchableAttributes: restrictSearchableAttributes,
    ),
  );

  final nameFilterString = 'name:"3A*"';
  final managerFilterString = 'cnpj:"09.5*"';
  final combinedFilterString = '$nameFilterString OR $managerFilterString';

  final queryHits = SearchForHits(
    indexName: indexName,
    filters: combinedFilterString,
    query: '',
    facetFilters: ['name', 'cnpj'],
    restrictSearchableAttributes: restrictSearchableAttributes,
  );

  final responseMulti = await client.searchForHits(requests: [queryHits]);

  final [searchResult] = responseMulti.toList();

  printHits(searchResult);

  final settings = await client.getSettings(indexName: indexName);
  print(settings);

  client.dispose();
}

My settings output is this one:

{
attributesForFaceting: 
[searchable(cnpj), filterOnly(isActive), searchable(managers), searchable(name), searchable(socialReason)], 

paginationLimitedTo: 1000, 

separatorsToIndex: , 

searchableAttributes: [name, cnpj, socialReason, managers], 

ranking: [typo, geo, words, filters, proximity, attribute, exact, custom], 

customRanking: [asc(name)], 
highlightPreTag: <em>, highlightPostTag: </em>, 
hitsPerPage: 10, 
minWordSizefor1Typo: 4, minWordSizefor2Typos: 8, 

queryType: prefixLast, 
removeWordsIfNoResults: none, 
exactOnSingleWordQuery: attribute, 

alternativesAsExact: [ignorePlurals, singleWordSynonym], 
maxValuesPerFacet: 2
}

I also tried this:

final nameFilterString = 'name:"3A"';
final managerFilterString = 'cnpj:"09.5"';
final combinedFilterString = '$nameFilterString OR $managerFilterString';

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions