From e82833f14a17b2b89f8ac80885677eca1ba19b3d Mon Sep 17 00:00:00 2001 From: Hussain Nagaria Date: Thu, 22 Apr 2021 14:21:29 +0530 Subject: [PATCH] feat: Basic Query + Autocomplete --- erpnext/templates/pages/product_search.py | 47 +++++++++++++++++++---- erpnext/www/all-products/search.css | 5 +++ erpnext/www/all-products/search.html | 6 ++- erpnext/www/all-products/search.js | 8 +++- 4 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 erpnext/www/all-products/search.css diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py index 76b007a77d..010e7a6832 100644 --- a/erpnext/templates/pages/product_search.py +++ b/erpnext/templates/pages/product_search.py @@ -11,7 +11,12 @@ from erpnext.e_commerce.shopping_cart.product_info import set_product_info_for_w # For SEARCH ------- import redis -from redisearch import Client, AutoCompleter, Suggestion, IndexDefinition, TextField, TagField +from redisearch import ( + Client, AutoCompleter, Query, + Suggestion, IndexDefinition, + TextField, TagField, + Document + ) WEBSITE_ITEM_INDEX = 'website_items_index' WEBSITE_ITEM_KEY_PREFIX = 'website_item:' @@ -62,21 +67,46 @@ def get_product_list(search=None, start=0, limit=12): @frappe.whitelist(allow_guest=True) def search(query): + if not query: + # TODO: return top/recent searches + return [] + ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000) + client = Client(WEBSITE_ITEM_INDEX, port=13000) suggestions = ac.get_suggestions(query, num=10) - print(suggestions) - return list([s.string for s in suggestions]) + + # Build a query + query_string = query + + for s in suggestions: + query_string += f"|({s.string})" + + q = Query(query_string) + + print(f"Executing query: {q.query_string()}") + + results = client.search(q) + results = list(map(convert_to_dict, results.docs)) + + print("SEARCH RESULTS ------------------\n ", results) + + return results + +def convert_to_dict(redis_search_doc): + return redis_search_doc.__dict__ def create_website_items_index(): '''Creates Index Definition''' + # CREATE index + client = Client(WEBSITE_ITEM_INDEX, port=13000) + # DROP if already exists try: client.drop_index() except: pass - # CREATE index - client = Client(WEBSITE_ITEM_INDEX, port=13000) + idx_def = IndexDefinition([WEBSITE_ITEM_KEY_PREFIX]) client.create_index( @@ -92,11 +122,11 @@ def insert_item_to_index(website_item_doc): r = redis.Redis("localhost", 13000) web_item = create_web_item_map(website_item_doc) r.hset(key, mapping=web_item) - insert_to_name_ac(website_item_doc.name) + insert_to_name_ac(website_item_doc.web_item_name, website_item_doc.name) -def insert_to_name_ac(name): +def insert_to_name_ac(web_name, doc_name): ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000) - ac.add_suggestions(Suggestion(name)) + ac.add_suggestions(Suggestion(web_name, payload=doc_name)) def create_web_item_map(website_item_doc): web_item = {} @@ -169,5 +199,6 @@ def get_cache_key(name): return f"{WEBSITE_ITEM_KEY_PREFIX}{name}" # TODO: Remove later +# Figure out a way to run this at startup define_autocomplete_dictionary() create_website_items_index() diff --git a/erpnext/www/all-products/search.css b/erpnext/www/all-products/search.css new file mode 100644 index 0000000000..ff0ca6ac9f --- /dev/null +++ b/erpnext/www/all-products/search.css @@ -0,0 +1,5 @@ +.item-thumb { + height: 50px; + width: 50px; + object-fit: cover; +} \ No newline at end of file diff --git a/erpnext/www/all-products/search.html b/erpnext/www/all-products/search.html index e7d437ad5f..ef74536286 100644 --- a/erpnext/www/all-products/search.html +++ b/erpnext/www/all-products/search.html @@ -1,7 +1,11 @@ {% extends "templates/web.html" %} - {% block title %}{{ _('Search') }}{% endblock %} + +{%- block head_include %} + +{% endblock -%} + {% block header %}
{{ _('Search Products') }}
{% endblock header %} diff --git a/erpnext/www/all-products/search.js b/erpnext/www/all-products/search.js index 02678a2c1a..2080f35c62 100644 --- a/erpnext/www/all-products/search.js +++ b/erpnext/www/all-products/search.js @@ -1,12 +1,16 @@ -console.log("search.js loaded"); +console.log("search.js reloaded"); const search_box = document.getElementById("search-box"); const results = document.getElementById("results"); function populateResults(data) { + console.log(data); html = "" for (let res of data.message) { - html += `
  • ${res}
  • ` + html += `
  • + + ${res.web_item_name} +
  • ` } console.log(html); results.innerHTML = html;