-
Notifications
You must be signed in to change notification settings - Fork 244
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1979 from frappe/search-improve
fix(HelpdeskSearch): Add report to evaluate search and improvements with the same
- Loading branch information
Showing
12 changed files
with
254 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,41 @@ | ||
import frappe | ||
from textblob import TextBlob | ||
from textblob.exceptions import MissingCorpusError | ||
|
||
from helpdesk.search import search as hd_search | ||
|
||
|
||
def get_nouns(text: str): | ||
blob = TextBlob(text) | ||
def get_nouns(blob: TextBlob): | ||
try: | ||
return [word for word, pos in blob.pos_tags if pos[0] == "N"] | ||
except LookupError: | ||
return [] | ||
|
||
|
||
def get_noun_phrases(blob: TextBlob): | ||
try: | ||
return blob.noun_phrases | ||
except (LookupError, MissingCorpusError): | ||
return [] | ||
|
||
|
||
@frappe.whitelist() | ||
def search(query: str): | ||
out = hd_search(query, only_articles=True) | ||
if not out: # fallback | ||
if nouns := get_nouns(query): | ||
query = " ".join(nouns) | ||
out = hd_search(query, only_articles=True) | ||
blob = TextBlob(query) | ||
if noun_phrases := get_noun_phrases(blob): | ||
and_query = " ".join(noun_phrases) | ||
or_query = "|".join(noun_phrases) | ||
out = hd_search(and_query, only_articles=True) or hd_search( | ||
or_query, only_articles=True | ||
) | ||
if not out and (nouns := get_nouns(blob)): | ||
and_query = " ".join(nouns) | ||
or_query = "|".join(nouns) | ||
out = hd_search(and_query, only_articles=True) or hd_search( | ||
or_query, only_articles=True | ||
) | ||
if not out: | ||
return [] | ||
return out[0].get("items", []) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright (c) 2024, Frappe Technologies and contributors | ||
// For license information, please see license.txt | ||
|
||
// frappe.ui.form.on("HD Stopword", { | ||
// refresh(frm) { | ||
|
||
// }, | ||
// }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
"actions": [], | ||
"allow_rename": 1, | ||
"autoname": "field:word", | ||
"creation": "2024-09-12 16:08:27.022111", | ||
"doctype": "DocType", | ||
"engine": "InnoDB", | ||
"field_order": [ | ||
"word", | ||
"column_break_jyol", | ||
"enabled" | ||
], | ||
"fields": [ | ||
{ | ||
"fieldname": "word", | ||
"fieldtype": "Data", | ||
"label": "Word", | ||
"unique": 1 | ||
}, | ||
{ | ||
"default": "1", | ||
"fieldname": "enabled", | ||
"fieldtype": "Check", | ||
"label": "Enabled" | ||
}, | ||
{ | ||
"fieldname": "column_break_jyol", | ||
"fieldtype": "Column Break" | ||
} | ||
], | ||
"index_web_pages_for_search": 1, | ||
"links": [], | ||
"modified": "2024-09-12 16:10:05.577545", | ||
"modified_by": "Administrator", | ||
"module": "Helpdesk", | ||
"name": "HD Stopword", | ||
"naming_rule": "By fieldname", | ||
"owner": "Administrator", | ||
"permissions": [ | ||
{ | ||
"create": 1, | ||
"delete": 1, | ||
"email": 1, | ||
"export": 1, | ||
"print": 1, | ||
"read": 1, | ||
"report": 1, | ||
"role": "System Manager", | ||
"share": 1, | ||
"write": 1 | ||
} | ||
], | ||
"sort_field": "creation", | ||
"sort_order": "DESC", | ||
"states": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright (c) 2024, Frappe Technologies and contributors | ||
# For license information, please see license.txt | ||
|
||
# import frappe | ||
from frappe.model.document import Document | ||
|
||
|
||
class HDStopword(Document): | ||
pass | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright (c) 2024, Frappe Technologies and Contributors | ||
# See license.txt | ||
|
||
# import frappe | ||
from frappe.tests.utils import FrappeTestCase | ||
|
||
|
||
class TestHDStopword(FrappeTestCase): | ||
pass |
Empty file.
13 changes: 13 additions & 0 deletions
13
helpdesk/helpdesk/report/ticket_search_analysis/ticket_search_analysis.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) 2024, Frappe Technologies and contributors | ||
// For license information, please see license.txt | ||
|
||
frappe.query_reports["Ticket-Search Analysis"] = { | ||
filters: [ | ||
// { | ||
// "fieldname": "my_filter", | ||
// "label": __("My Filter"), | ||
// "fieldtype": "Data", | ||
// "reqd": 1, | ||
// }, | ||
], | ||
}; |
38 changes: 38 additions & 0 deletions
38
helpdesk/helpdesk/report/ticket_search_analysis/ticket_search_analysis.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"add_total_row": 0, | ||
"columns": [], | ||
"creation": "2024-09-11 22:31:05.837918", | ||
"disabled": 0, | ||
"docstatus": 0, | ||
"doctype": "Report", | ||
"filters": [], | ||
"idx": 0, | ||
"is_standard": "Yes", | ||
"letterhead": null, | ||
"modified": "2024-09-11 22:31:05.837918", | ||
"modified_by": "Administrator", | ||
"module": "Helpdesk", | ||
"name": "Ticket-Search Analysis", | ||
"owner": "Administrator", | ||
"prepared_report": 0, | ||
"ref_doctype": "HD Ticket", | ||
"report_name": "Ticket-Search Analysis", | ||
"report_type": "Script Report", | ||
"roles": [ | ||
{ | ||
"role": "System Manager" | ||
}, | ||
{ | ||
"role": "Agent" | ||
}, | ||
{ | ||
"role": "Support Team" | ||
}, | ||
{ | ||
"role": "Supported Site User" | ||
}, | ||
{ | ||
"role": "External Agent" | ||
} | ||
] | ||
} |
71 changes: 71 additions & 0 deletions
71
helpdesk/helpdesk/report/ticket_search_analysis/ticket_search_analysis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Copyright (c) 2024, Frappe Technologies and contributors | ||
# For license information, please see license.txt | ||
|
||
import frappe | ||
from frappe import _ | ||
|
||
from helpdesk.api.article import search | ||
|
||
|
||
def execute(filters: dict | None = None): | ||
"""Return columns and data for the report. | ||
This is the main entry point for the report. It accepts the filters as a | ||
dictionary and should return columns and data. It is called by the framework | ||
every time the report is refreshed or a filter is updated. | ||
""" | ||
columns = get_columns() | ||
data = get_data() | ||
|
||
return columns, data | ||
|
||
|
||
def get_columns() -> list[dict]: | ||
"""Return columns for the report. | ||
One field definition per column, just like a DocType field definition. | ||
""" | ||
return [ | ||
{ | ||
"label": _("Subject"), | ||
"fieldname": "subject", | ||
"fieldtype": "Data", | ||
}, | ||
{ | ||
"label": _("Top Result"), | ||
"fieldname": "top_res", | ||
"fieldtype": "Text", | ||
}, | ||
{ | ||
"label": _("Search Score"), | ||
"fieldname": "score", | ||
"fieldtype": "Float", | ||
}, | ||
] | ||
|
||
|
||
def get_top_res(search_term: str) -> float: | ||
"""Return the search score for the top result for the search term.""" | ||
res = search(search_term) | ||
headings = "" | ||
score = 0 | ||
for item in res: | ||
headings += item["headings"] or item["subject"] | ||
headings += "\n" | ||
score += item["score"] | ||
return headings, score | ||
|
||
|
||
def get_data() -> list[list]: | ||
"""Return data for the report. | ||
The report data is a list of rows, with each row being a list of cell values. | ||
""" | ||
tickets = frappe.get_all( | ||
"HD Ticket", {"agent_group": ["like", "%FC%"]}, ["name", "subject"], limit=100 | ||
) | ||
for ticket in tickets: | ||
ticket["top_res"], ticket["score"] = get_top_res(ticket["subject"]) | ||
return [ | ||
[ticket["subject"], ticket["top_res"], ticket["score"]] for ticket in tickets | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters