mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 03:23:43 +08:00
FIX: Post blurb incorrect when search contains a phrase match.
If the blurb generated is not around the search term, we will not be able to highlight it on the client side.
This commit is contained in:
parent
1799820256
commit
dae0bb4c67
|
@ -0,0 +1 @@
|
||||||
|
export const PHRASE_MATCH_REGEXP_PATTERN = '<%= Search::PHRASE_MATCH_REGEXP_PATTERN %>';
|
|
@ -1,7 +1,13 @@
|
||||||
|
import { PHRASE_MATCH_REGEXP_PATTERN } from "discourse/lib/concerns/search-constants";
|
||||||
|
|
||||||
export default function($elem, term) {
|
export default function($elem, term) {
|
||||||
if (!_.isEmpty(term)) {
|
if (!_.isEmpty(term)) {
|
||||||
// special case ignore "l" which is used for magic sorting
|
// special case ignore "l" which is used for magic sorting
|
||||||
let words = _.reject(term.match(/"[^"]+"|[^\s]+/g), t => t === "l");
|
let words = _.reject(
|
||||||
|
term.match(new RegExp(`${PHRASE_MATCH_REGEXP_PATTERN}|[^\s]+`, "g")),
|
||||||
|
t => t === "l"
|
||||||
|
);
|
||||||
|
|
||||||
words = words.map(w => w.replace(/^"(.*)"$/, "$1"));
|
words = words.map(w => w.replace(/^"(.*)"$/, "$1"));
|
||||||
$elem.highlight(words, { className: "search-highlight", wordsOnly: true });
|
$elem.highlight(words, { className: "search-highlight", wordsOnly: true });
|
||||||
}
|
}
|
||||||
|
|
|
@ -727,6 +727,8 @@ class Search
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
PHRASE_MATCH_REGEXP_PATTERN = '"([^"]+)"'
|
||||||
|
|
||||||
def posts_query(limit, opts = nil)
|
def posts_query(limit, opts = nil)
|
||||||
opts ||= {}
|
opts ||= {}
|
||||||
|
|
||||||
|
@ -770,7 +772,7 @@ class Search
|
||||||
# D is for cooked
|
# D is for cooked
|
||||||
weights = @in_title ? 'A' : (SiteSetting.tagging_enabled ? 'ABCD' : 'ABD')
|
weights = @in_title ? 'A' : (SiteSetting.tagging_enabled ? 'ABCD' : 'ABD')
|
||||||
posts = posts.where("post_search_data.search_data @@ #{ts_query(weight_filter: weights)}")
|
posts = posts.where("post_search_data.search_data @@ #{ts_query(weight_filter: weights)}")
|
||||||
exact_terms = @term.scan(/"([^"]+)"/).flatten
|
exact_terms = @term.scan(Regexp.new(PHRASE_MATCH_REGEXP_PATTERN)).flatten
|
||||||
|
|
||||||
exact_terms.each do |exact|
|
exact_terms.each do |exact|
|
||||||
posts = posts.where("posts.raw ilike :exact OR topics.title ilike :exact", exact: "%#{exact}%")
|
posts = posts.where("posts.raw ilike :exact OR topics.title ilike :exact", exact: "%#{exact}%")
|
||||||
|
|
|
@ -70,7 +70,16 @@ class Search
|
||||||
|
|
||||||
if term
|
if term
|
||||||
terms = term.split(/\s+/)
|
terms = term.split(/\s+/)
|
||||||
blurb = TextHelper.excerpt(cooked, terms.first, radius: blurb_length / 2, seperator: " ")
|
phrase = terms.first
|
||||||
|
|
||||||
|
if phrase =~ Regexp.new(Search::PHRASE_MATCH_REGEXP_PATTERN)
|
||||||
|
phrase = Regexp.last_match[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
blurb = TextHelper.excerpt(cooked, phrase,
|
||||||
|
radius: blurb_length / 2,
|
||||||
|
seperator: " "
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
blurb = TextHelper.truncate(cooked, length: blurb_length, seperator: " ") if blurb.blank?
|
blurb = TextHelper.truncate(cooked, length: blurb_length, seperator: " ") if blurb.blank?
|
||||||
|
|
|
@ -304,16 +304,35 @@ describe Search do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'searching for a post' do
|
context 'searching for a post' do
|
||||||
let!(:reply) { Fabricate(:basic_reply, topic: topic, user: topic.user) }
|
let!(:reply) do
|
||||||
let(:result) { Search.execute('quotes', type_filter: 'topic', include_blurbs: true) }
|
Fabricate(:post_with_long_raw_content,
|
||||||
|
topic: topic,
|
||||||
|
user: topic.user,
|
||||||
|
).tap { |post| post.update!(raw: "#{post.raw} elephant") }
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_blurb) do
|
||||||
|
"...to satisfy any test conditions that require content longer than the typical test post raw content. elephant"
|
||||||
|
end
|
||||||
|
|
||||||
it 'returns the post' do
|
it 'returns the post' do
|
||||||
expect(result).to be_present
|
result = Search.execute('elephant',
|
||||||
expect(result.posts.length).to eq(1)
|
type_filter: 'topic',
|
||||||
p = result.posts[0]
|
include_blurbs: true
|
||||||
expect(p.topic.id).to eq(topic.id)
|
)
|
||||||
expect(p.id).to eq(reply.id)
|
|
||||||
expect(result.blurb(p)).to eq("this reply has no quotes")
|
expect(result.posts).to contain_exactly(reply)
|
||||||
|
expect(result.blurb(reply)).to eq(expected_blurb)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the right post and blurb for searches with phrase' do
|
||||||
|
result = Search.execute('"elephant"',
|
||||||
|
type_filter: 'topic',
|
||||||
|
include_blurbs: true
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result.posts).to contain_exactly(reply)
|
||||||
|
expect(result.blurb(reply)).to eq(expected_blurb)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user