Итак, в настоящее время я работаю над проектом, в котором нужно показать более 1 миллиона документов (сертификаты/брак/смерть/дома/и т. д.), и все они должны быть отображены (да, я знаю, звучит не очень хорошо). но оно тоже есть). В настоящее время я использую Elastic Search, Python, Flask и Docker в своем проекте. И у меня есть функция просмотра всех с некоторыми включенными search_after и PIT, но я продолжаю получать различные ошибки, такие как Jinja Undefine, Type Error, Unresolved и т. д. Я также получаю ошибки, когда изображение не отображается. Я прочитал документацию по Elastic Search и старался изо всех сил использовать то, что у меня есть, но безуспешно. Так что мне нужна помощь. Ниже прилагается мой код для просмотра всего.
@blueprint.route("/browse-all", methods=["GET"])
def browse_all():
"""
This view function handles GET requests for the Browse All page.
A query is made for the initial page of certificates shown.
:return: Template for the browse all page and a list of certificates to display.
Redirect to public.view_certificate if only one certificate is returned.
"""
# Get default year range/values
try:
cached_year_range = get_year_range()
if cached_year_range and cached_year_range.year_min and cached_year_range.year_max:
default_year_range_value = f"{cached_year_range.year_min} - {cached_year_range.year_max}"
else:
raise ValueError("Invalid year range")
except Exception as e:
current_app.logger.error(f"Error getting year range: {str(e)}")
default_year_range_value = "1855 - 1949" # Fallback range
form = BrowseAllForm()
page = request.args.get('page', 1, type=int)
page_size = 50
# Set up variables for search
q_list = []
for key, value in request.args.items():
if key != 'page' and value:
if key == "year_range":
year_range = [int(year) for year in value.split() if year.isdigit()]
if len(year_range) == 2:
q_list.append(Q("range", year={"gte": year_range[0], "lte": year_range[1]}))
elif key in ["first_name", "last_name"]:
q_list.append(Q("multi_match", query=value.capitalize(), fields=[key, f"spouse_{key}"]))
elif key == "certificate_type" and value == "marriage":
q_list.append(Q("terms", cert_type=[certificate_types.MARRIAGE, certificate_types.MARRIAGE_LICENSE]))
else:
q_list.append(Q("match", **{key: value}))
q = Q("bool", must=q_list) if q_list else Q("match_all")
# Define the sort order
sort_order = [{"_doc": "asc"}]
# Create a new PIT for each request
pit = es.open_point_in_time(index="certificates", keep_alive="1m")
pit_id = pit['id']
# Get search_after from request arguments
search_after = request.args.get('search_after')
if search_after:
search_after = search_after.split(',')
# Construct the search body
body = {
"size": page_size,
"query": q.to_dict(),
"sort": sort_order,
"pit": {
"id": pit_id,
"keep_alive": "1m"
}
}
if search_after and page > 1:
body["search_after"] = search_after
# Perform the search
try:
response = es.search(body=body)
except Exception as e:
current_app.logger.error(f"Elasticsearch error: {str(e)}")
return render_template("public/error.html", error_message="An error occurred while searching. Please try again.")
# Get the total count
count = response["hits"]["total"]["value"]
# If only one certificate is returned, go directly to the view certificate page
if count == 1:
es.close_point_in_time(id=pit_id)
return redirect(url_for("public.view_certificate", certificate_id=response["hits"]["hits"][0]["_id"]))
# Process hits to include image URLs
processed_hits = []
for hit in response['hits']['hits']:
processed_hit = hit['_source']
processed_hit['_id'] = hit['_id']
if 'image_url' not in processed_hit:
processed_hit['image_url'] = url_for('static', filename='images/placeholder.png')
processed_hits.append(processed_hit)
# Set form data from previous form submissions
for field in form:
if field.name in request.args:
field.data = request.args[field.name]
# Simplified remove_filters logic
remove_filters = {}
for key, value in request.args.items():
if key not in ['page', 'search_after'] and value:
if not (key == "year_range" and value == default_year_range_value):
label = value
if key == "certificate_type":
label = certificate_types.CERTIFICATE_TYPE_VALUES.get(value, value)
elif key == "county":
label = counties.COUNTY_VALUES.get(value, value)
args_without_filter = request.args.copy()
args_without_filter.pop(key)
new_url = url_for('public.browse_all', **args_without_filter)
remove_filters[key] = (label, new_url)
# Define pagination
pagination = Pagination(page=page, total=count, per_page=page_size, css_framework="bootstrap4")
next_page = page + 1 if len(response['hits']['hits']) == page_size else None
# Prepare next_args for the next page URL
next_args = request.args.copy()
if next_page:
next_args['page'] = next_page
if response['hits']['hits']:
next_args['search_after'] = ','.join(map(str, response['hits']['hits'][-1]['sort']))
else:
next_args.pop('page', None)
next_args.pop('search_after', None)
# Close the PIT
es.close_point_in_time(id=pit_id)
return render_template(
"public/browse_all.html",
form=form,
certificates=processed_hits,
pagination=pagination,
remove_filters=remove_filters,
num_results=count,
next_page=next_page,
next_args=next_args,
certificate_types=certificate_types,
counties=counties,
min=min,
default_year_range_value=default_year_range_value
)
Я попробовал search_after отдельно, но вскоре мы обновимся до ElasticSearch 8, и, согласно документации, для search_after потребуется PIT, поэтому я реализовал оба. По сути, мне нужно, чтобы пользователь мог перейти на страницу 201, 202, 203 и т. д. и т. п. Пока больше ничего не будет показано.
Итак, в настоящее время я работаю над проектом, в котором нужно показать более 1 миллиона документов (сертификаты/брак/смерть/дома/и т. д.), и все они должны быть отображены (да, я знаю, звучит не очень хорошо). но оно тоже есть). В настоящее время я использую Elastic Search, Python, Flask и Docker в своем проекте. И у меня есть функция просмотра всех с некоторыми включенными search_after и PIT, но я продолжаю получать различные ошибки, такие как Jinja Undefine, Type Error, Unresolved и т. д. Я также получаю ошибки, когда изображение не отображается. Я прочитал документацию по Elastic Search и старался изо всех сил использовать то, что у меня есть, но безуспешно. Так что мне нужна помощь. Ниже прилагается мой код для просмотра всего. [code]@blueprint.route("/browse-all", methods=["GET"]) def browse_all(): """ This view function handles GET requests for the Browse All page. A query is made for the initial page of certificates shown.
:return: Template for the browse all page and a list of certificates to display. Redirect to public.view_certificate if only one certificate is returned. """ # Get default year range/values try: cached_year_range = get_year_range() if cached_year_range and cached_year_range.year_min and cached_year_range.year_max: default_year_range_value = f"{cached_year_range.year_min} - {cached_year_range.year_max}" else: raise ValueError("Invalid year range") except Exception as e: current_app.logger.error(f"Error getting year range: {str(e)}") default_year_range_value = "1855 - 1949" # Fallback range
for key, value in request.args.items(): if key != 'page' and value: if key == "year_range": year_range = [int(year) for year in value.split() if year.isdigit()] if len(year_range) == 2: q_list.append(Q("range", year={"gte": year_range[0], "lte": year_range[1]})) elif key in ["first_name", "last_name"]: q_list.append(Q("multi_match", query=value.capitalize(), fields=[key, f"spouse_{key}"])) elif key == "certificate_type" and value == "marriage": q_list.append(Q("terms", cert_type=[certificate_types.MARRIAGE, certificate_types.MARRIAGE_LICENSE])) else: q_list.append(Q("match", **{key: value}))
q = Q("bool", must=q_list) if q_list else Q("match_all")
# Define the sort order sort_order = [{"_doc": "asc"}]
# Create a new PIT for each request pit = es.open_point_in_time(index="certificates", keep_alive="1m") pit_id = pit['id']
# Get search_after from request arguments search_after = request.args.get('search_after') if search_after: search_after = search_after.split(',')
# Construct the search body body = { "size": page_size, "query": q.to_dict(), "sort": sort_order, "pit": { "id": pit_id, "keep_alive": "1m" } }
if search_after and page > 1: body["search_after"] = search_after
# Perform the search try: response = es.search(body=body) except Exception as e: current_app.logger.error(f"Elasticsearch error: {str(e)}") return render_template("public/error.html", error_message="An error occurred while searching. Please try again.")
# Get the total count count = response["hits"]["total"]["value"]
# If only one certificate is returned, go directly to the view certificate page if count == 1: es.close_point_in_time(id=pit_id) return redirect(url_for("public.view_certificate", certificate_id=response["hits"]["hits"][0]["_id"]))
# Process hits to include image URLs processed_hits = [] for hit in response['hits']['hits']: processed_hit = hit['_source'] processed_hit['_id'] = hit['_id'] if 'image_url' not in processed_hit: processed_hit['image_url'] = url_for('static', filename='images/placeholder.png') processed_hits.append(processed_hit)
# Set form data from previous form submissions for field in form: if field.name in request.args: field.data = request.args[field.name]
# Simplified remove_filters logic remove_filters = {} for key, value in request.args.items(): if key not in ['page', 'search_after'] and value: if not (key == "year_range" and value == default_year_range_value): label = value if key == "certificate_type": label = certificate_types.CERTIFICATE_TYPE_VALUES.get(value, value) elif key == "county": label = counties.COUNTY_VALUES.get(value, value)
# Prepare next_args for the next page URL next_args = request.args.copy() if next_page: next_args['page'] = next_page if response['hits']['hits']: next_args['search_after'] = ','.join(map(str, response['hits']['hits'][-1]['sort'])) else: next_args.pop('page', None) next_args.pop('search_after', None)
# Close the PIT es.close_point_in_time(id=pit_id)
return render_template( "public/browse_all.html", form=form, certificates=processed_hits, pagination=pagination, remove_filters=remove_filters, num_results=count, next_page=next_page, next_args=next_args, certificate_types=certificate_types, counties=counties, min=min, default_year_range_value=default_year_range_value ) [/code] Я попробовал search_after отдельно, но вскоре мы обновимся до ElasticSearch 8, и, согласно документации, для search_after потребуется PIT, поэтому я реализовал оба. По сути, мне нужно, чтобы пользователь мог перейти на страницу 201, 202, 203 и т. д. и т. п. Пока больше ничего не будет показано.
Итак, в настоящее время я работаю над проектом, в котором нужно показать более 1 миллиона документов (сертификаты/брак/смерть/дома/и т. д.), и все они должны быть отображены (да, я знаю, звучит не очень хорошо). но оно тоже есть). В настоящее время...
Я работаю над старым сайтом Codeigniter 3.1.9 на PHP 8.2.12. Мой вопрос: возможно ли разделить результаты поиска из базы данных, скажем, на 20 результатов на страницу плюс еще 2 строки заголовков для компиляции всей страницы (страниц) с нумерацией...
Я работаю над старым сайтом Codeigniter 3.1.9 на PHP 8.2.12. Мой вопрос: возможно ли разделить результаты поиска из базы данных, скажем, на 20 результатов на страницу плюс еще 2 строки заголовков для компиляции всей страницы (страниц) с нумерацией...