Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] q for searches #175

Open
strarsis opened this issue Mar 11, 2022 · 4 comments
Open

[Feature Request] q for searches #175

strarsis opened this issue Mar 11, 2022 · 4 comments

Comments

@strarsis
Copy link

strarsis commented Mar 11, 2022

react-admin often uses q as full text search parameter.
Currently FeathersJS will try to use q as column (which usually doesn't exist in the table) and report a query error.

How can this functionality be added? Must the data provider handle this or a hook in FeathersJS app?

Edit: Just using source="fieldName[$like]" sadly won't work as the field name is automatically escaped (probably already in react-admin), also the value is not automatically wrapped in % for an open start + end of string.

@strarsis
Copy link
Author

strarsis commented Mar 12, 2022

Currently I use this server-side (FeathersJS) hook to achieve the functionality:

import { HookContext } from '@feathersjs/feathers';
const withSearch = (sourceField: string = 'q', targetField: string = 'name', caseSensitive: boolean = false) => {
  return async (context: HookContext) => {
    if (context.type === 'before') {
      if (context?.params?.query && context.params.query[sourceField]) {
        // convert to like field (KnexJS FeathersJS Adapter)
        // @see https://github.com/feathersjs-ecosystem/feathers-knex/blob/master/test/index.test.js#L205
        const value = context.params.query[sourceField];

        // Note: Some databases like SQLite don't support `$ilike` (case-insensitive `$like`)...
        const targetOp = '$like';

        // ... hence internally handle case sensitivity checks
        const targetValue = caseSensitive ? value : value.toLowerCase();

        // set new parameter that is understood by KnexJS FeathersJS Adapter
        // e.g. `fieldName[$like] = '%value%'`
        context.params.query[targetField] = {
          [targetOp]: `\%${targetValue}\%`, // `%[...]%` for open text start + end
        };

        // clean up old field from query (otherwise causes query error (non-existing column))
        delete context.params.query[sourceField];

        return context;
      }
    }

  }
}
export default withSearch;
const withSearchHook = withSearch('q', 'name');
// [...]
export default {
  before: {
    // [...]
    find: [
      withSearchHook,
    ],
    // [...]
    get: [
      withSearchHook,
    ],
    // [...]
// [...]

So for
the GET request URL
https://localhost:3030/items?q=test
the query q=TeSt is rewritten to
the new query `name[$like] = '%test%'.

The old q=TeSt query is removed as it causes a SQL error (column doesn't exist) or is somehow otherwise excluded anyway.

This results in a full-text search in the name field (note: in that specific field only, it is not a full-text search for the whole record, that would be something different) (without case-sensitivity (false)).

@josx
Copy link
Owner

josx commented Mar 15, 2022

Did you try customQueryOperator as an option?

https://github.com/josx/ra-data-feathers#data-provider-restclient

@strarsis
Copy link
Author

strarsis commented Mar 15, 2022

@josx: Would customQueryOperators: [ '$like' ] allow react-admin to do those searches as full text search in the name field?
SQLite as backend doesn't support $ilike (case-insensitive searches) and the search query has to be surrounded with % to allow it to match partially. The knex FeathersJS adapter is used.

The customQueryOperator option indeed looks like it would offer this functionality and it would be great to just pass a parameter to get it.

@josx
Copy link
Owner

josx commented Mar 15, 2022

customQueryOperator is operator to be use on filter key when quering feathers.
Allows to use custom operators from various feathers-database-adapters.
Any params.filter included in custom operators will be sent to feathers.

Please check tests
https://github.com/josx/ra-data-feathers/blob/master/test/restClient.spec.js#L293

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants