Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
cd8596fe
Commit
cd8596fe
authored
Oct 21, 2021
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use full text search when searching issues
parent
2b195836
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
122 additions
and
5 deletions
+122
-5
app/controllers/concerns/issuable_collections.rb
app/controllers/concerns/issuable_collections.rb
+4
-0
app/finders/issuable_finder.rb
app/finders/issuable_finder.rb
+8
-0
app/models/concerns/pg_full_text_searchable.rb
app/models/concerns/pg_full_text_searchable.rb
+17
-2
config/feature_flags/development/issues_full_text_search.yml
config/feature_flags/development/issues_full_text_search.yml
+8
-0
lib/gitlab/issuables_count_for_state.rb
lib/gitlab/issuables_count_for_state.rb
+1
-1
spec/controllers/dashboard_controller_spec.rb
spec/controllers/dashboard_controller_spec.rb
+16
-1
spec/controllers/projects/issues_controller_spec.rb
spec/controllers/projects/issues_controller_spec.rb
+15
-1
spec/features/issues/filtered_search/filter_issues_spec.rb
spec/features/issues/filtered_search/filter_issues_spec.rb
+2
-0
spec/finders/issues_finder_spec.rb
spec/finders/issues_finder_spec.rb
+23
-0
spec/models/concerns/pg_full_text_searchable_spec.rb
spec/models/concerns/pg_full_text_searchable_spec.rb
+28
-0
No files found.
app/controllers/concerns/issuable_collections.rb
View file @
cd8596fe
...
...
@@ -117,6 +117,10 @@ module IssuableCollections
options
[
:attempt_group_search_optimizations
]
=
true
end
if
collection_type
==
'Issue'
&&
Feature
.
enabled?
(
:issues_full_text_search
,
@project
||
@group
,
default_enabled: :yaml
)
options
[
:attempt_full_text_search
]
=
true
end
params
.
permit
(
finder_type
.
valid_params
).
merge
(
options
)
end
end
...
...
app/finders/issuable_finder.rb
View file @
cd8596fe
...
...
@@ -37,6 +37,7 @@
# attempt_project_search_optimizations: boolean
# crm_contact_id: integer
# crm_organization_id: integer
# attempt_full_text_search: boolean
#
class
IssuableFinder
prepend
FinderWithCrossProjectAccess
...
...
@@ -46,6 +47,7 @@ class IssuableFinder
requires_cross_project_access
unless:
->
{
params
.
project?
}
FULL_TEXT_SEARCH_TERM_REGEX
=
/\A[\p{ASCII}|\p{Latin}]+\z/
.
freeze
NEGATABLE_PARAMS_HELPER_KEYS
=
%i[project_id scope status include_subgroups]
.
freeze
attr_accessor
:current_user
,
:params
...
...
@@ -331,6 +333,8 @@ class IssuableFinder
return
items
if
items
.
is_a?
(
ActiveRecord
::
NullRelation
)
return
items
if
Feature
.
enabled?
(
:disable_anonymous_search
,
type: :ops
)
&&
current_user
.
nil?
return
items
.
pg_full_text_search
(
search
)
if
use_full_text_search?
if
use_cte_for_search?
cte
=
Gitlab
::
SQL
::
CTE
.
new
(
klass
.
table_name
,
items
)
...
...
@@ -341,6 +345,10 @@ class IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
def
use_full_text_search?
params
[
:attempt_full_text_search
]
&&
params
[
:search
]
=~
FULL_TEXT_SEARCH_TERM_REGEX
end
# rubocop: disable CodeReuse/ActiveRecord
def
by_iids
(
items
)
params
[
:iids
].
present?
?
items
.
where
(
iid:
params
[
:iids
])
:
items
...
...
app/models/concerns/pg_full_text_searchable.rb
View file @
cd8596fe
...
...
@@ -13,9 +13,9 @@
# This module sets up an after_commit hook that updates the search data
# when the searchable columns are changed.
#
# This also adds a `full_text_search` scope so you can do:
# This also adds a `
pg_
full_text_search` scope so you can do:
#
# Model.full_text_search("some search term")
# Model.
pg_
full_text_search("some search term")
module
PgFullTextSearchable
extend
ActiveSupport
::
Concern
...
...
@@ -82,5 +82,20 @@ module PgFullTextSearchable
update_search_data!
end
end
def
pg_full_text_search
(
search_term
)
search_data_table
=
reflect_on_association
(
:search_data
).
klass
.
arel_table
joins
(
:search_data
).
where
(
Arel
::
Nodes
::
InfixOperation
.
new
(
'@@'
,
search_data_table
[
:search_vector
],
Arel
::
Nodes
::
NamedFunction
.
new
(
'websearch_to_tsquery'
,
[
Arel
::
Nodes
.
build_quoted
(
TEXT_SEARCH_DICTIONARY
),
Arel
::
Nodes
.
build_quoted
(
search_term
)]
)
)
)
end
end
end
config/feature_flags/development/issues_full_text_search.yml
0 → 100644
View file @
cd8596fe
---
name
:
issues_full_text_search
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71913
rollout_issue_url
:
milestone
:
'
14.5'
type
:
development
group
:
group::project management
default_enabled
:
false
lib/gitlab/issuables_count_for_state.rb
View file @
cd8596fe
...
...
@@ -144,7 +144,7 @@ module Gitlab
def
params_include_filters?
non_filtering_params
=
%i[
scope state sort group_id include_subgroups
attempt_group_search_optimizations non_archived issue_types
attempt_group_search_optimizations
attempt_full_text_search
non_archived issue_types
]
finder
.
params
.
except
(
*
non_filtering_params
).
values
.
any?
...
...
spec/controllers/dashboard_controller_spec.rb
View file @
cd8596fe
...
...
@@ -13,7 +13,22 @@ RSpec.describe DashboardController do
end
describe
'GET issues'
do
it_behaves_like
'issuables list meta-data'
,
:issue
,
:issues
context
'when issues_full_text_search is disabled'
do
before
do
stub_feature_flags
(
issues_full_text_search:
false
)
end
it_behaves_like
'issuables list meta-data'
,
:issue
,
:issues
end
context
'when issues_full_text_search is enabled'
do
before
do
stub_feature_flags
(
issues_full_text_search:
true
)
end
it_behaves_like
'issuables list meta-data'
,
:issue
,
:issues
end
it_behaves_like
'issuables requiring filter'
,
:issues
end
...
...
spec/controllers/projects/issues_controller_spec.rb
View file @
cd8596fe
...
...
@@ -72,7 +72,21 @@ RSpec.describe Projects::IssuesController do
project
.
add_developer
(
user
)
end
it_behaves_like
"issuables list meta-data"
,
:issue
context
'when issues_full_text_search is disabled'
do
before
do
stub_feature_flags
(
issues_full_text_search:
false
)
end
it_behaves_like
'issuables list meta-data'
,
:issue
end
context
'when issues_full_text_search is enabled'
do
before
do
stub_feature_flags
(
issues_full_text_search:
true
)
end
it_behaves_like
'issuables list meta-data'
,
:issue
end
it_behaves_like
'set sort order from user preference'
do
let
(
:sorting_param
)
{
'updated_asc'
}
...
...
spec/features/issues/filtered_search/filter_issues_spec.rb
View file @
cd8596fe
...
...
@@ -497,6 +497,8 @@ RSpec.describe 'Filter issues', :js do
end
it
'filters issues by searched text containing special characters'
do
stub_feature_flags
(
issues_full_text_search:
false
)
issue
=
create
(
:issue
,
project:
project
,
author:
user
,
title:
"issue with !@
\#
{$%^&*()-+"
)
search
=
'!@#{$%^&*()-+'
...
...
spec/finders/issues_finder_spec.rb
View file @
cd8596fe
...
...
@@ -632,6 +632,29 @@ RSpec.describe IssuesFinder do
end
end
context
'filtering by issue term using full-text search'
do
let
(
:params
)
{
{
search:
search_term
,
attempt_full_text_search:
true
}
}
let_it_be
(
:english
)
{
create
(
:issue
,
project:
project1
,
title:
'title'
,
description:
'something english'
)
}
let_it_be
(
:japanese
)
{
create
(
:issue
,
project:
project1
,
title:
'日本語 title'
,
description:
'another english description'
)
}
context
'with latin search term'
do
let
(
:search_term
)
{
'title english'
}
it
'returns matching issues'
do
expect
(
issues
).
to
contain_exactly
(
english
,
japanese
)
end
end
context
'with non-latin search term'
do
let
(
:search_term
)
{
'日本語'
}
it
'returns matching issues'
do
expect
(
issues
).
to
contain_exactly
(
japanese
)
end
end
end
context
'filtering by issues iids'
do
let
(
:params
)
{
{
iids:
[
issue3
.
iid
]
}
}
...
...
spec/models/concerns/pg_full_text_searchable_spec.rb
View file @
cd8596fe
...
...
@@ -55,6 +55,34 @@ RSpec.describe PgFullTextSearchable do
end
end
describe
'.pg_full_text_search'
do
let
(
:english
)
{
model_class
.
create!
(
title:
'title'
,
description:
'something english'
)
}
let
(
:with_accent
)
{
model_class
.
create!
(
title:
'Jürgen'
,
description:
'Ærøskøbing'
)
}
let
(
:japanese
)
{
model_class
.
create!
(
title:
'日本語 title'
,
description:
'another english description'
)
}
before
do
model_class
.
pg_full_text_searchable
columns:
[{
name:
'title'
,
weight:
'A'
},
{
name:
'description'
,
weight:
'B'
}]
[
english
,
with_accent
,
japanese
].
each
(
&
:update_search_data!
)
end
it
'searches across all fields'
do
expect
(
model_class
.
pg_full_text_search
(
'title english'
)).
to
contain_exactly
(
english
,
japanese
)
end
it
'searches for exact term with quotes'
do
expect
(
model_class
.
pg_full_text_search
(
'"something english"'
)).
to
contain_exactly
(
english
)
end
it
'ignores accents'
do
expect
(
model_class
.
pg_full_text_search
(
'jurgen'
)).
to
contain_exactly
(
with_accent
)
end
it
'does not support searching by non-Latin characters'
do
expect
(
model_class
.
pg_full_text_search
(
'日本'
)).
to
be_empty
end
end
describe
'#update_search_data!'
do
let
(
:model
)
{
model_class
.
create!
(
title:
'title'
,
description:
'description'
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment