def on_get(self, req, resp): """Run a search.""" query = req.get_param('q', default='') start = int(req.get_param('start', default=0)) # TODO multi-site: decide which site to use based on query (header, URL?) search_site = config.default_search_site search_client = get_search_connection(search_site.index_name) try: num = min(int(req.get_param('num', default=DEFAULT_NUM)), MAX_NUM) except ValueError: num = DEFAULT_NUM q = parse(query, search_site).paging(start, num) try: res = search_client.search(q) except (redis.exceptions.ResponseError, UnicodeDecodeError) as e: log.error("Search query failed: %s", e) total = 0 docs = [] else: docs = res.docs total = res.total docs = transform_documents(docs, search_site, q.query_string()) resp.body = json.dumps({"total": total, "results": docs})
def on_get(self, req, resp): """Run a search.""" query = req.get_param('q', default='') from_url = req.get_param('from_url', default='') start = int(req.get_param('start', default=0)) site_url = req.get_param('site', default=None) # Return an error if a site URL was given but it's invalid. if site_url and site_url not in self.app_config.sites: raise falcon.HTTPBadRequest( "Invalid site", "You must specify a valid search site.") # Use the default search site if no site URL was given. if not site_url: site_url = self.app_config.default_search_site.url search_site = self.app_config.sites.get(site_url) section = indexer.get_section(site_url, from_url) try: num = min(int(req.get_param('num', default=DEFAULT_NUM)), MAX_NUM) except ValueError: num = DEFAULT_NUM index_alias = self.keys.index_alias(search_site.url) search_client = get_search_connection(index_alias) q = parse(query, section, search_site).paging(start, num) try: res = search_client.search(q) except (redis.exceptions.ResponseError, UnicodeDecodeError) as e: log.error("Search query failed: %s", e) total = 0 docs = [] else: docs = res.docs total = res.total docs = transform_documents(docs, search_site, q.query_string()) resp.body = json.dumps({"total": total, "results": docs})
def search(query): q = parse(query, config.default_search_site.synonym_groups) try: res = client.search(q) except redis.exceptions.ResponseError as e: log.error("Search query failed: %s", e) total = 0 docs = [] else: total = res.total docs = transform_documents(res.docs) print(f"Hits: {total}") print() for doc in docs: print(f"{doc['hierarchy']} - {doc['title']}") if doc['section_title']: print(f"[{doc['section_title']}]") print(doc['url']) print(doc['body'] or "NO BODY") print()
def test_strips_dash_star_postfixes(): query = parse("python-*", config.default_search_site) assert query.query_string() == "python*"
def test_allow_fuzzy_search_for_non_synonym_terms(): query = parse("test*", config.default_search_site) assert query.query_string() == "test*"
def test_exact_search_for_synonym_terms(): query = parse("insight*", config.default_search_site) assert query.query_string() == "insight"
def test_highlights_fields(): query = parse("test", config.default_search_site) for field in ['title', 'body', 'section_title']: assert field in query._highlight_fields
def test_summarizes_body(): query = parse("test", config.default_search_site) assert 'body' in query._summarize_fields
def test_strips_unsafe_chars(): query = parse("this is a [test]", config.default_search_site) assert query.query_string() == "this is a test"
def test_boosts_current_section_if_given(): query = parse("test", "test", config.default_search_site) assert query.query_string() == "((@s:test) => {$weight: 10} test) | test"