feat: Basic Query + Autocomplete

This commit is contained in:
Hussain Nagaria 2021-04-22 14:21:29 +05:30 committed by marination
parent 0c47f3a876
commit e82833f14a
4 changed files with 55 additions and 11 deletions

View File

@ -11,7 +11,12 @@ from erpnext.e_commerce.shopping_cart.product_info import set_product_info_for_w
# For SEARCH ------- # For SEARCH -------
import redis 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_INDEX = 'website_items_index'
WEBSITE_ITEM_KEY_PREFIX = 'website_item:' 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) @frappe.whitelist(allow_guest=True)
def search(query): def search(query):
if not query:
# TODO: return top/recent searches
return []
ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000) ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000)
client = Client(WEBSITE_ITEM_INDEX, port=13000)
suggestions = ac.get_suggestions(query, num=10) 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(): def create_website_items_index():
'''Creates Index Definition''' '''Creates Index Definition'''
# CREATE index
client = Client(WEBSITE_ITEM_INDEX, port=13000)
# DROP if already exists # DROP if already exists
try: try:
client.drop_index() client.drop_index()
except: except:
pass pass
# CREATE index
client = Client(WEBSITE_ITEM_INDEX, port=13000)
idx_def = IndexDefinition([WEBSITE_ITEM_KEY_PREFIX]) idx_def = IndexDefinition([WEBSITE_ITEM_KEY_PREFIX])
client.create_index( client.create_index(
@ -92,11 +122,11 @@ def insert_item_to_index(website_item_doc):
r = redis.Redis("localhost", 13000) r = redis.Redis("localhost", 13000)
web_item = create_web_item_map(website_item_doc) web_item = create_web_item_map(website_item_doc)
r.hset(key, mapping=web_item) 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 = 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): def create_web_item_map(website_item_doc):
web_item = {} web_item = {}
@ -169,5 +199,6 @@ def get_cache_key(name):
return f"{WEBSITE_ITEM_KEY_PREFIX}{name}" return f"{WEBSITE_ITEM_KEY_PREFIX}{name}"
# TODO: Remove later # TODO: Remove later
# Figure out a way to run this at startup
define_autocomplete_dictionary() define_autocomplete_dictionary()
create_website_items_index() create_website_items_index()

View File

@ -0,0 +1,5 @@
.item-thumb {
height: 50px;
width: 50px;
object-fit: cover;
}

View File

@ -1,7 +1,11 @@
{% extends "templates/web.html" %} {% extends "templates/web.html" %}
{% block title %}{{ _('Search') }}{% endblock %} {% block title %}{{ _('Search') }}{% endblock %}
{%- block head_include %}
<link rel="stylesheet" href="search.css">
{% endblock -%}
{% block header %} {% block header %}
<div class="mb-6">{{ _('Search Products') }}</div> <div class="mb-6">{{ _('Search Products') }}</div>
{% endblock header %} {% endblock header %}

View File

@ -1,12 +1,16 @@
console.log("search.js loaded"); console.log("search.js reloaded");
const search_box = document.getElementById("search-box"); const search_box = document.getElementById("search-box");
const results = document.getElementById("results"); const results = document.getElementById("results");
function populateResults(data) { function populateResults(data) {
console.log(data);
html = "" html = ""
for (let res of data.message) { for (let res of data.message) {
html += `<li>${res}</li>` html += `<li>
<img class="item-thumb" src="${res.thumbnail || ''}" />
<a href="/${res.route}">${res.web_item_name}</a>
</li>`
} }
console.log(html); console.log(html);
results.innerHTML = html; results.innerHTML = html;