1
0
mirror of https://github.com/peeringdb/peeringdb.git synced 2024-05-11 05:55:09 +00:00
Files
peeringdb-peeringdb/peeringdb_server/search.py

113 lines
2.4 KiB
Python
Raw Normal View History

2018-11-08 19:45:21 +00:00
from django.db.models import Q
from django.conf import settings
from peeringdb_server.models import (
InternetExchange,
Network,
Facility,
Organization,
)
# import time
import unidecode
from haystack.query import SearchQuerySet
from haystack.inputs import Exact
searchable_models = [
Organization,
Network,
InternetExchange,
Facility,
]
2019-12-05 16:57:52 +00:00
def unaccent(v):
return unidecode.unidecode(v).lower()
2018-11-08 19:45:21 +00:00
2019-12-05 16:57:52 +00:00
def prepare_term(term):
try:
if len(term) == 1:
int(term)
term = f"AS{term}"
except ValueError:
pass
2018-11-08 19:45:21 +00:00
return unaccent(term)
2018-11-08 19:45:21 +00:00
def make_search_query(term):
if not term:
return SearchQuerySet().none()
2018-11-08 19:45:21 +00:00
term = prepare_term(term)
2018-11-08 19:45:21 +00:00
term_filters = Q(content=term) | Q(content__startswith=term)
2018-11-08 19:45:21 +00:00
return SearchQuerySet().filter(term_filters, status=Exact("ok"))
2018-11-08 19:45:21 +00:00
def make_name_search_query(term):
if not term:
return SearchQuerySet().none()
term = prepare_term(term)
2018-11-08 19:45:21 +00:00
term_filters = Q(name=term) | Q(name__startswith=term)
2018-11-08 19:45:21 +00:00
return SearchQuerySet().filter(term_filters, status=Exact("ok"))
2018-11-08 19:45:21 +00:00
def make_autocomplete_query(term):
if not term:
return SearchQuerySet().none()
2018-11-08 19:45:21 +00:00
term = prepare_term(term)
return SearchQuerySet().autocomplete(auto=term).filter(status=Exact("ok"))
2018-11-08 19:45:21 +00:00
def search(term, autocomplete=False):
2018-11-08 19:45:21 +00:00
"""
Search searchable objects (ixp, network, facility ...) by term
Returns result dict
"""
# t0 = time.time()
2018-11-08 19:45:21 +00:00
if autocomplete:
search_query = make_autocomplete_query(term)
limit = settings.SEARCH_RESULTS_AUTOCOMPLETE_LIMIT
2018-11-08 19:45:21 +00:00
else:
search_query = make_search_query(term)
limit = settings.SEARCH_RESULTS_LIMIT
2018-11-08 19:45:21 +00:00
search_tags = ("fac", "ix", "net", "org")
result = dict([(tag, []) for tag in search_tags])
for sq in search_query.models(*searchable_models)[:limit]:
model = sq.model
tag = model.HandleRef.tag
if tag == "org":
org_id = sq.pk
else:
org_id = sq.org_id
result[tag].append(
{
"id": sq.pk,
"name": sq.result_name,
"org_id": int(org_id),
"score": sq.score,
}
)
2018-11-08 19:45:21 +00:00
for k, items in list(result.items()):
# TODO: sort by score (wait until v2 search results)
2018-11-08 19:45:21 +00:00
result[k] = sorted(items, key=lambda row: row.get("name"))
# print("done", time.time() - t0)
2018-11-08 19:45:21 +00:00
return result