FEATURE: include tag and category context in search (#217)
Previous to this we just included title/body.. tags and category structure can be very critical for decision making.
This commit is contained in:
parent
b0310f90d3
commit
d75e3ca82b
|
@ -154,17 +154,33 @@ module DiscourseAi::AiBot::Commands
|
|||
end
|
||||
|
||||
@last_num_results = posts.length
|
||||
# this is the general pattern from core
|
||||
# if there are millions of hidden tags it may fail
|
||||
hidden_tags = nil
|
||||
|
||||
if posts.blank?
|
||||
{ args: search_args, rows: [], instruction: "nothing was found, expand your search" }
|
||||
else
|
||||
format_results(posts, args: search_args) do |post|
|
||||
{
|
||||
category_names = [
|
||||
post.topic.category&.parent_category&.name,
|
||||
post.topic.category&.name,
|
||||
].compact.join(" > ")
|
||||
row = {
|
||||
title: post.topic.title,
|
||||
url: Discourse.base_path + post.url,
|
||||
excerpt: post.excerpt,
|
||||
created: post.created_at,
|
||||
category: category_names,
|
||||
}
|
||||
|
||||
if SiteSetting.tagging_enabled
|
||||
hidden_tags ||= DiscourseTagging.hidden_tag_names
|
||||
# using map over pluck to avoid n+1 (assuming caller preloading)
|
||||
tags = post.topic.tags.map(&:name) - hidden_tags
|
||||
row[:tags] = tags.join(", ") if tags.present?
|
||||
end
|
||||
row
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,19 +9,19 @@ RSpec.describe DiscourseAi::AiBot::Commands::ReadCommand do
|
|||
fab!(:tag_funny) { Fabricate(:tag, name: "funny") }
|
||||
fab!(:tag_sad) { Fabricate(:tag, name: "sad") }
|
||||
fab!(:tag_hidden) { Fabricate(:tag, name: "hidden") }
|
||||
fab!(:staff_tag_group) { Fabricate(:tag_group, name: "Staff only", tag_names: ["hidden"]) }
|
||||
fab!(:staff_tag_group) do
|
||||
tag_group = Fabricate.build(:tag_group, name: "Staff only", tag_names: ["hidden"])
|
||||
|
||||
tag_group.permissions = [
|
||||
[Group::AUTO_GROUPS[:staff], TagGroupPermission.permission_types[:full]],
|
||||
]
|
||||
tag_group.save!
|
||||
tag_group
|
||||
end
|
||||
fab!(:topic_with_tags) do
|
||||
Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden])
|
||||
end
|
||||
|
||||
let(:staff) { Group::AUTO_GROUPS[:staff] }
|
||||
let(:full) { TagGroupPermission.permission_types[:full] }
|
||||
|
||||
before do
|
||||
staff_tag_group.permissions = [[staff, full]]
|
||||
staff_tag_group.save!
|
||||
end
|
||||
|
||||
describe "#process" do
|
||||
it "can read a topic" do
|
||||
topic_id = topic_with_tags.id
|
||||
|
|
|
@ -9,9 +9,28 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||
before { SearchIndexer.enable }
|
||||
after { SearchIndexer.disable }
|
||||
|
||||
fab!(:parent_category) { Fabricate(:category, name: "animals") }
|
||||
fab!(:category) { Fabricate(:category, parent_category: parent_category, name: "amazing-cat") }
|
||||
|
||||
fab!(:tag_funny) { Fabricate(:tag, name: "funny") }
|
||||
fab!(:tag_sad) { Fabricate(:tag, name: "sad") }
|
||||
fab!(:tag_hidden) { Fabricate(:tag, name: "hidden") }
|
||||
fab!(:staff_tag_group) do
|
||||
tag_group = Fabricate.build(:tag_group, name: "Staff only", tag_names: ["hidden"])
|
||||
|
||||
tag_group.permissions = [
|
||||
[Group::AUTO_GROUPS[:staff], TagGroupPermission.permission_types[:full]],
|
||||
]
|
||||
tag_group.save!
|
||||
tag_group
|
||||
end
|
||||
fab!(:topic_with_tags) do
|
||||
Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden])
|
||||
end
|
||||
|
||||
describe "#process" do
|
||||
it "can handle no results" do
|
||||
post1 = Fabricate(:post)
|
||||
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||
|
||||
results = search.process(query: "order:fake ABDDCDCEDGDG")
|
||||
|
@ -42,7 +61,7 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||
hyde_embedding,
|
||||
)
|
||||
|
||||
post1 = Fabricate(:post)
|
||||
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||
|
||||
DiscourseAi::Embeddings::VectorRepresentations::AllMpnetBaseV2
|
||||
|
@ -60,7 +79,7 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||
it "supports subfolder properly" do
|
||||
Discourse.stubs(:base_path).returns("/subfolder")
|
||||
|
||||
post1 = Fabricate(:post)
|
||||
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||
|
||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||
|
||||
|
@ -68,8 +87,22 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||
expect(results[:rows].to_s).to include("/subfolder" + post1.url)
|
||||
end
|
||||
|
||||
it "returns category and tags" do
|
||||
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||
results = search.process(user: post1.user.username)
|
||||
|
||||
row = results[:rows].first
|
||||
category = row[results[:column_names].index("category")]
|
||||
|
||||
expect(category).to eq("animals > amazing-cat")
|
||||
|
||||
tags = row[results[:column_names].index("tags")]
|
||||
expect(tags).to eq("funny, sad")
|
||||
end
|
||||
|
||||
it "can handle limits" do
|
||||
post1 = Fabricate(:post)
|
||||
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||
_post2 = Fabricate(:post, user: post1.user)
|
||||
_post3 = Fabricate(:post, user: post1.user)
|
||||
|
||||
|
@ -78,7 +111,6 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||
|
||||
results = search.process(limit: 2, user: post1.user.username)
|
||||
|
||||
expect(results[:column_names].length).to eq(4)
|
||||
expect(results[:rows].length).to eq(2)
|
||||
|
||||
# just searching for everything
|
||||
|
|
Loading…
Reference in New Issue