Cms: Lightswitch fields are not properly searchable.

Created on 5 May 2020  Â·  9Comments  Â·  Source: craftcms/cms

Description

The keywords for a lightswitch field within the searchindex table are erroneous. While true values are stored correctly as 1, false values result in an empty string (expected 0). Thus making it impossible to search for the false state due to the LIKE operator.

Additional info

  • Craft version: Craft Pro 3.4.18
  • PHP version: 7.4.3
  • Database driver & version: MySQL 5.5.5
enhancement extensibility

Most helpful comment

Great idea. Just added new EVENT_DEFINE_KEYWORDS events to both elements and custom fields, for Craft 3.5.

Here’s how you could hook into a Lightswitch field’s keywords from a module:

use yii\base\Event;
use craft\fields\Lightswitch;
use craft\events\DefineFieldKeywordsEvent;

Event::on(Lightswitch::class, Lightswitch::EVENT_DEFINE_KEYWORDS, function(DefineFieldKeywordsEvent $e) {
    /** @var Lightswitch $field */
    $field = $e->sender;

    if ($field->handle === 'myLightswitchField') {
        $e->keywords = $e->value ? 'foo' : 'bar';
        $e->handled = true;
    }
});

All 9 comments

Instead of using the search parameter, you should use your Lightswitch fields’ dedicated query parameters to filter results by their values. See https://docs.craftcms.com/v3/lightswitch-fields.html#querying-elements-with-lightswitch-fields for details.

Okay. I'll just avoid the issue, then ...

To clarify, search is not meant to be a precise tool, so little idiosyncrasies like this are normal and out of our control for the most part.

I understand that search isn't meant to be a precise tool.

But, if craft\fields\Lightswitch implemented its own getSearchKeywords method which returned numeric values, directly, instead of relying on the version inhereted from craft\base\Field (where StringHelper::toString causes this discrepancy), this wouldn't be a problem.

So this seems like an easily resolvable oversight and not some idiosyncrasy outside your control.

Honestly the most awkward thing about this to me is that it’s even returning 1 for enabled values. That’s not meant to be a search keyword. If I were to add that method to Lightswitch fields, it would be so that an empty string is always returned. You’re going to be much better off using the field’s element query param, which is significantly faster than going through search.

I've since refactored my code to use query parameters, instead. So while this is a non-issue for my project, I was still curious about the implications on search overall. And to your point, it doesn't seem the lightswitch field should be searchable at all given the current implementation. Search would need to be refactored to require field name specification on such field types to even provide relevant results.

Exactly… as it is now it’s really just adding a bunch of random 1s to search indexes that don’t add any real value in practice. I won’t change it for now because I don’t want to break existing templates, but will probably stop including 1 keywords in Craft 4.0.

Perhaps this should be converted into a feature request for customizable search keywords? For example, a lightswitch named "On-site" could be configured to save "on-site" as the keyword when true or "off-site" when false.

Great idea. Just added new EVENT_DEFINE_KEYWORDS events to both elements and custom fields, for Craft 3.5.

Here’s how you could hook into a Lightswitch field’s keywords from a module:

use yii\base\Event;
use craft\fields\Lightswitch;
use craft\events\DefineFieldKeywordsEvent;

Event::on(Lightswitch::class, Lightswitch::EVENT_DEFINE_KEYWORDS, function(DefineFieldKeywordsEvent $e) {
    /** @var Lightswitch $field */
    $field = $e->sender;

    if ($field->handle === 'myLightswitchField') {
        $e->keywords = $e->value ? 'foo' : 'bar';
        $e->handled = true;
    }
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

rynpsc picture rynpsc  Â·  3Comments

bitboxfw picture bitboxfw  Â·  3Comments

mattstein picture mattstein  Â·  3Comments

lukebailey picture lukebailey  Â·  3Comments

brandonkelly picture brandonkelly  Â·  3Comments