Commit 70bf6dc7 authored by Robert Speicher's avatar Robert Speicher
Browse files

Merge branch 'trigram-index-searching' into 'master'

Refactor searching and use PostgreSQL trigram indexes for significantly
improved performance

Related issue: https://gitlab.com/gitlab-org/gitlab-ce/issues/13743.

Also fixes #12410

See merge request !2987
parents ee14ac68 67143e25
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ v 8.6.0 (unreleased)
  - Return empty array instead of 404 when commit has no statuses in commit status API
  - Decrease the font size and the padding of the `.anchor` icons used in the README (Roberto Dip)
  - Rewrite logo to simplify SVG code (Sean Lang)
  - Refactor and greatly improve search performance
  - Add support for cross-project label references
  - Update documentation to reflect Guest role not being enforced on internal projects
  - Allow search for logged out users
+4 −1
Original line number Diff line number Diff line
@@ -52,7 +52,10 @@ def group_projects(current_user, group)

  def all_projects(current_user)
    if current_user
      [current_user.authorized_projects, public_and_internal_projects]
      [
        *current_user.project_relations,
        public_and_internal_projects
      ]
    else
      [Project.public_only]
    end
+17 −3
Original line number Diff line number Diff line
@@ -46,9 +46,23 @@ class Runner < ActiveRecord::Base

    acts_as_taggable

    # Searches for runners matching the given query.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # This method performs a *partial* match on tokens, thus a query for "a"
    # will match any runner where the token contains the letter "a". As a result
    # you should *not* use this method for non-admin purposes as otherwise users
    # might be able to query a list of all runners.
    #
    # query - The search query as a String
    #
    # Returns an ActiveRecord::Relation.
    def self.search(query)
      where('LOWER(ci_runners.token) LIKE :query OR LOWER(ci_runners.description) like :query',
            query: "%#{query.try(:downcase)}%")
      t = arel_table
      pattern = "%#{query}%"

      where(t[:token].matches(pattern).or(t[:description].matches(pattern)))
    end

    def set_default_values
+19 −2
Original line number Diff line number Diff line
@@ -61,12 +61,29 @@ module Issuable
  end

  module ClassMethods
    # Searches for records with a matching title.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # query - The search query as a String
    #
    # Returns an ActiveRecord::Relation.
    def search(query)
      where("LOWER(title) like :query", query: "%#{query.downcase}%")
      where(arel_table[:title].matches("%#{query}%"))
    end

    # Searches for records with a matching title or description.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # query - The search query as a String
    #
    # Returns an ActiveRecord::Relation.
    def full_search(query)
      where("LOWER(title) like :query OR LOWER(description) like :query", query: "%#{query.downcase}%")
      t = arel_table
      pattern = "%#{query}%"

      where(t[:title].matches(pattern).or(t[:description].matches(pattern)))
    end

    def sort(method)
+11 −1
Original line number Diff line number Diff line
@@ -33,8 +33,18 @@ class Group < Namespace
  after_destroy :post_destroy_hook

  class << self
    # Searches for groups matching the given query.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # query - The search query as a String
    #
    # Returns an ActiveRecord::Relation.
    def search(query)
      where("LOWER(namespaces.name) LIKE :query or LOWER(namespaces.path) LIKE :query", query: "%#{query.downcase}%")
      table   = Namespace.arel_table
      pattern = "%#{query}%"

      where(table[:name].matches(pattern).or(table[:path].matches(pattern)))
    end

    def sort(method)
Loading