Skip to content

Support exact match search queries in dashboards #2745

@FabriceCastel

Description

@FabriceCastel
  • What would you like to be able to do? Can you provide some examples?

I'd like to be able to set a search_exact: true option on a searchable field in my dashboard such that when administrate executes the search query, it matches results using an equality constraint instead of a LIKE '%my-string%' substring search. I mainly want to do this for performance reasons when searching for eg. all emails sent to a given email address, from a table that might hold a very large number of records.

The filter feature wasn't well suited to this because it requires the filter options to be defined upfront, and in a case like this I don't think that I'd really want to include every possible email in the filter options even if I could.

  • How could we go about implementing that?

I've put together a proof of concept in repo based off an older fork and the diffs are pretty minimal:

lib/administrate/field/base.rb

+      def self.search_exact?
+        false
+      end

lib/administrate/field/deferred.rb

+      def self.search_exact?
+        false
+      end

lib/administrate/search.rb

    def query_template
      search_attributes.map do |attr|
        table_name = query_table_name(attr)
        searchable_fields(attr).map do |field|
          column_name = column_to_query(field)
+         if attribute_types[attr].search_exact?
+           "LOWER(#{table_name}.#{column_name}) = ?"
+         else
+           "LOWER(CAST(#{table_name}.#{column_name} AS CHAR(256))) LIKE ?"
+         end
        end.join(" OR ")
      end.join(" OR ")
    end

    # [...]

    def query_values
+     search_attributes.flat_map do |attr|
+       attribute_type = attribute_types[attr]
+
+       if attribute_type.search_exact?
+         ["#{term.mb_chars.downcase}"] * searchable_fields(attr).count
+       else
+         ["%#{term.mb_chars.downcase}%"] * searchable_fields(attr).count
+       end
+     end
    end

There were a couple of specs that needed updating to validate the new option.

  • Can you think of other approaches to the problem?

No, but to be fair this is my first time digging into administrate. Also, caveat: I haven't tested this with non-text fields, this might still require the CAST to work across all types given the LOWER.

Metadata

Metadata

Assignees

No one assigned

    Labels

    searchfinding things through our models

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions