From d864399a09d80d5cf1c9cf823a4df5213ff8a6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?KMY=EF=BC=88=E9=9B=AA=E3=81=82=E3=81=99=E3=81=8B=EF=BC=89?= Date: Fri, 12 Jan 2024 10:27:35 +0900 Subject: [PATCH] =?UTF-8?q?Fix:=20#370=20=E3=83=80=E3=83=96=E3=83=AB?= =?UTF-8?q?=E3=82=AF=E3=82=AA=E3=83=BC=E3=83=88=E3=82=92=E4=BD=BF=E3=81=A3?= =?UTF-8?q?=E3=81=9F=E6=97=A5=E6=9C=AC=E8=AA=9E=E6=A4=9C=E7=B4=A2=E3=81=8C?= =?UTF-8?q?=E5=8A=B9=E3=81=8B=E3=81=AA=E3=81=84=20(#448)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: #370 ダブルクオートを使った日本語検索が効かない * Add test for multiple words * Improve test * 入れ替え * 単語検索のテスト --- app/chewy/accounts_index.rb | 2 +- app/chewy/public_statuses_index.rb | 2 +- app/chewy/statuses_index.rb | 2 +- app/lib/search_query_transformer.rb | 4 +- .../services/statuses_search_service_spec.rb | 50 +++++++++++++++++++ 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/app/chewy/accounts_index.rb b/app/chewy/accounts_index.rb index 888a638c9c..a7a0df40da 100644 --- a/app/chewy/accounts_index.rb +++ b/app/chewy/accounts_index.rb @@ -92,6 +92,6 @@ class AccountsIndex < Chewy::Index field(:domain, type: 'keyword', value: ->(account) { account.domain || '' }) field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } - field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(account) { account.searchable_text }) + field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(account) { account.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'natural') } end end diff --git a/app/chewy/public_statuses_index.rb b/app/chewy/public_statuses_index.rb index 806fd42ecb..6ae13418f4 100644 --- a/app/chewy/public_statuses_index.rb +++ b/app/chewy/public_statuses_index.rb @@ -87,7 +87,7 @@ class PublicStatusesIndex < Chewy::Index root date_detection: false do field(:id, type: 'long') field(:account_id, type: 'long') - field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(status) { status.searchable_text }) + field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) }) field(:language, type: 'keyword') field(:domain, type: 'keyword', value: ->(status) { status.account.domain || '' }) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index fbf59d6404..ff6e0e7672 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -107,7 +107,7 @@ class StatusesIndex < Chewy::Index root date_detection: false do field(:id, type: 'long') field(:account_id, type: 'long') - field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(status) { status.searchable_text }) + field(:text, type: 'text', analyzer: 'sudachi_analyzer', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) }) field(:searchable_by, type: 'long', value: ->(status) { status.searchable_by }) field(:mentioned_by, type: 'long', value: ->(status) { status.mentioned_by }) diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index ed73751cb5..89b16c1d2e 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -237,7 +237,7 @@ class SearchQueryTransformer < Parslet::Transform else # Memo for checking when manually merge # { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } } - { match_phrase: { text: { query: @term } } } + { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } } end end end @@ -251,6 +251,8 @@ class SearchQueryTransformer < Parslet::Transform end def to_query + # Memo for checking when manually merge + # { match_phrase: { text: { query: @phrase } } } { match_phrase: { text: { query: @phrase } } } end end diff --git a/spec/search/services/statuses_search_service_spec.rb b/spec/search/services/statuses_search_service_spec.rb index 51245f7354..8bc236e4a6 100644 --- a/spec/search/services/statuses_search_service_spec.rb +++ b/spec/search/services/statuses_search_service_spec.rb @@ -213,4 +213,54 @@ describe StatusesSearchService do end end end + + describe 'a local user posts with search keyword' do + subject do + described_class.new.call(search_keyword, account, limit: 10).map(&:id) + end + + let(:search_keyword) { 'ohagi' } + let(:status_text) { 'りんごを食べました' } + + let(:alice) { Fabricate(:user).account } + let(:account) { alice } + let!(:status) { Fabricate(:status, text: status_text, account: alice, searchability: :public) } + + before do + alice.update!(username: 'alice') + StatusesIndex.import! + end + + shared_examples 'hit status' do |name, keyword| + context name do + let(:search_keyword) { keyword } + + it 'a status hits' do + expect(subject.count).to eq 1 + expect(subject).to include status.id + end + end + end + + shared_examples 'does not hit status' do |name, keyword| + context name do + let(:search_keyword) { keyword } + + it 'no statuses hit' do + expect(subject.count).to eq 0 + end + end + end + + it_behaves_like 'hit status', 'when search with word', 'りんご' + it_behaves_like 'hit status', 'when search with multiple words', 'りんご 食べる' + it_behaves_like 'does not hit status', 'when search with multiple words but does not hit half', 'りんご 茹でる' + it_behaves_like 'hit status', 'when search with letter in word', 'ご' + it_behaves_like 'does not hit status', 'when double quote search with letter in word', '"ご"' + it_behaves_like 'hit status', 'when search with fixed word', '"りんご"' + it_behaves_like 'hit status', 'when double quote search with multiple letter in word', 'り ご' + it_behaves_like 'does not hit status', 'when double quote search with multiple letter in word but does not contain half', 'ず ご' + it_behaves_like 'hit status', 'when specify user name', 'りんご from:alice' + it_behaves_like 'does not hit status', 'when specify not existing user name', 'りんご from:ohagi' + end end