diff --git a/ee/changelogs/unreleased/search-issue-and-mr-id.yml b/ee/changelogs/unreleased/search-issue-and-mr-id.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5d12546d6ff910be933bfd3f767aec55c2aafc58
--- /dev/null
+++ b/ee/changelogs/unreleased/search-issue-and-mr-id.yml
@@ -0,0 +1,5 @@
+---
+title: Make searching issues/MRs by IID even easier
+merge_request: 40467
+author:
+type: added
diff --git a/ee/lib/elastic/latest/issue_class_proxy.rb b/ee/lib/elastic/latest/issue_class_proxy.rb
index daf97f2c500579bbde5100eea7902f3add53362b..b5f69cda2750acf9aec8feb240f2c45debdef138 100644
--- a/ee/lib/elastic/latest/issue_class_proxy.rb
+++ b/ee/lib/elastic/latest/issue_class_proxy.rb
@@ -8,7 +8,14 @@ def elastic_search(query, options: {})
           if query =~ /#(\d+)\z/
             iid_query_hash(Regexp.last_match(1))
           else
-            basic_query_hash(%w(title^2 description), query)
+            fields = %w(title^2 description)
+
+            # We can only allow searching the iid field if the query is
+            # just a number, otherwise Elasticsearch will error since this
+            # field is type integer.
+            fields << "iid^3" if query =~ /\A\d+\z/
+
+            basic_query_hash(fields, query)
           end
 
         options[:features] = 'issues'
diff --git a/ee/lib/elastic/latest/merge_request_class_proxy.rb b/ee/lib/elastic/latest/merge_request_class_proxy.rb
index cdcf76a0069217ee29f48d14d4890d0d4d3f6206..19f63869bdbf5a750663d9db4ef4d40a3710864f 100644
--- a/ee/lib/elastic/latest/merge_request_class_proxy.rb
+++ b/ee/lib/elastic/latest/merge_request_class_proxy.rb
@@ -8,7 +8,14 @@ def elastic_search(query, options: {})
           if query =~ /\!(\d+)\z/
             iid_query_hash(Regexp.last_match(1))
           else
-            basic_query_hash(%w(title^2 description), query)
+            fields = %w(title^2 description)
+
+            # We can only allow searching the iid field if the query is
+            # just a number, otherwise Elasticsearch will error since this
+            # field is type integer.
+            fields << "iid^3" if query =~ /\A\d+\z/
+
+            basic_query_hash(fields, query)
           end
 
         options[:features] = 'merge_requests'
diff --git a/ee/spec/lib/gitlab/elastic/search_results_spec.rb b/ee/spec/lib/gitlab/elastic/search_results_spec.rb
index fbeb46634c6196029522572ae31457d71e618f7b..e0b9dca34943578199274c3fe30759b3167954fd 100644
--- a/ee/spec/lib/gitlab/elastic/search_results_spec.rb
+++ b/ee/spec/lib/gitlab/elastic/search_results_spec.rb
@@ -118,14 +118,14 @@
       @issue_2 = create(
         :issue,
         project: project_1,
-        title: 'Issue 2',
+        title: 'Issue Two',
         description: 'Hello world, here I am!',
         iid: 2
       )
       @issue_3 = create(
         :issue,
         project: project_2,
-        title: 'Issue 3',
+        title: 'Issue Three',
         iid: 2
       )
 
@@ -138,9 +138,7 @@
       results = described_class.new(user, 'hello world', limit_projects)
       issues = results.objects('issues')
 
-      expect(issues).to include @issue_1
-      expect(issues).to include @issue_2
-      expect(issues).not_to include @issue_3
+      expect(issues).to contain_exactly(@issue_1, @issue_2)
       expect(results.issues_count).to eq 2
     end
 
@@ -155,9 +153,15 @@
       results = described_class.new(user, '#2', limit_projects, public_and_internal_projects: false)
       issues = results.objects('issues')
 
-      expect(issues).not_to include @issue_1
-      expect(issues).to include @issue_2
-      expect(issues).not_to include @issue_3
+      expect(issues).to contain_exactly(@issue_2)
+      expect(results.issues_count).to eq 1
+    end
+
+    it 'can also find an issue by iid without the prefixed #' do
+      results = described_class.new(user, '2', limit_projects, public_and_internal_projects: false)
+      issues = results.objects('issues')
+
+      expect(issues).to contain_exactly(@issue_2)
       expect(results.issues_count).to eq 1
     end
 
@@ -421,7 +425,7 @@
         :conflict,
         source_project: project_1,
         target_project: project_1,
-        title: 'Merge Request 2',
+        title: 'Merge Request Two',
         description: 'Hello world, here I am!',
         iid: 2
       )
@@ -429,7 +433,7 @@
         :merge_request,
         source_project: project_2,
         target_project: project_2,
-        title: 'Merge Request 3',
+        title: 'Merge Request Three',
         iid: 2
       )
 
@@ -439,12 +443,10 @@
     it_behaves_like 'a paginated object', 'merge_requests'
 
     it 'lists found merge requests' do
-      results = described_class.new(user, 'hello world', limit_projects)
+      results = described_class.new(user, 'hello world', limit_projects, public_and_internal_projects: false)
       merge_requests = results.objects('merge_requests')
 
-      expect(merge_requests).to include @merge_request_1
-      expect(merge_requests).to include @merge_request_2
-      expect(merge_requests).not_to include @merge_request_3
+      expect(merge_requests).to contain_exactly(@merge_request_1, @merge_request_2)
       expect(results.merge_requests_count).to eq 2
     end
 
@@ -456,12 +458,18 @@
     end
 
     it 'lists merge request when search by a valid iid' do
-      results = described_class.new(user, '#2', limit_projects)
+      results = described_class.new(user, '!2', limit_projects, public_and_internal_projects: false)
+      merge_requests = results.objects('merge_requests')
+
+      expect(merge_requests).to contain_exactly(@merge_request_2)
+      expect(results.merge_requests_count).to eq 1
+    end
+
+    it 'can also find an issue by iid without the prefixed !' do
+      results = described_class.new(user, '2', limit_projects, public_and_internal_projects: false)
       merge_requests = results.objects('merge_requests')
 
-      expect(merge_requests).not_to include @merge_request_1
-      expect(merge_requests).to include @merge_request_2
-      expect(merge_requests).not_to include @merge_request_3
+      expect(merge_requests).to contain_exactly(@merge_request_2)
       expect(results.merge_requests_count).to eq 1
     end