From 465f7490890cd2f4327169621ed50ff16477c943 Mon Sep 17 00:00:00 2001 From: Jon Pentland Date: Tue, 19 Mar 2024 17:16:06 +0000 Subject: [PATCH] Create custom search field configuration and query --- src/collective/elasticsearch/indexes.py | 22 +++++++++++++++------- src/collective/elasticsearch/interfaces.py | 7 +++++++ src/collective/elasticsearch/utils.py | 8 ++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/collective/elasticsearch/indexes.py b/src/collective/elasticsearch/indexes.py index e686703..00671f9 100644 --- a/src/collective/elasticsearch/indexes.py +++ b/src/collective/elasticsearch/indexes.py @@ -1,6 +1,7 @@ from Acquisition import aq_base from Acquisition import aq_parent from collective.elasticsearch import logger +from collective.elasticsearch.utils import getSearchFields from datetime import date from datetime import datetime from DateTime import DateTime @@ -214,14 +215,21 @@ def get_query(self, name, value): # ES doesn't care about * like zope catalog does clean_value = value.strip("*") if value else "" queries = [{"match_phrase": {name: {"query": clean_value, "slop": 2}}}] - if name in ("Title", "SearchableText"): + for search in getSearchFields(): + # we add the base search field above, skip duplicating here... + if search == name: + continue # titles have most importance... we override here... - queries.append( - {"match_phrase_prefix": {"Title": {"query": clean_value, "boost": 2}}} - ) - if name != "Title": - queries.append({"match": {name: {"query": clean_value}}}) - + if search == "Title": + queries.append( + { + "match_phrase_prefix": { + "Title": {"query": clean_value, "boost": 2} + } + } + ) + else: + queries.append({"match": {search: {"query": clean_value}}}) return queries diff --git a/src/collective/elasticsearch/interfaces.py b/src/collective/elasticsearch/interfaces.py index e03ca1e..6b7b6e1 100644 --- a/src/collective/elasticsearch/interfaces.py +++ b/src/collective/elasticsearch/interfaces.py @@ -68,6 +68,13 @@ class IElasticSettings(Interface): value_type=schema.TextLine(title="Index"), ) + search_fields = schema.Set( + title="Indexes which are used when performing a search. " + "Note, indexes should also be present in the Index setting.", + default={"Title", "Description", "SearchableText"}, + value_type=schema.TextLine(title="Search Fields"), + ) + sniff_on_start = schema.Bool(title="Sniff on start", default=False, required=False) sniff_on_connection_fail = schema.Bool( diff --git a/src/collective/elasticsearch/utils.py b/src/collective/elasticsearch/utils.py index 98795dd..c19a772 100644 --- a/src/collective/elasticsearch/utils.py +++ b/src/collective/elasticsearch/utils.py @@ -68,6 +68,14 @@ def getESOnlyIndexes(): except (KeyError, AttributeError): return {"Title", "Description", "SearchableText"} +def getSearchFields(): + settings = get_settings() + try: + search_fields = settings.search_fields + return set(search_fields) if search_fields else set() + except (KeyError, AttributeError): + return {"Title", "SearchableText"} + def batches(data: list, size: int) -> List[List]: """Create a batch of lists from a base list."""