Skip to content

Instantly share code, notes, and snippets.

@chiatt
Last active December 10, 2024 14:40
Show Gist options
  • Save chiatt/d6f361b81b6e501ed370b6f2dfa6f851 to your computer and use it in GitHub Desktop.
Save chiatt/d6f361b81b6e501ed370b6f2dfa6f851 to your computer and use it in GitHub Desktop.
An ES Mapping Modifier to add related descriptor names to a resources indexed document
"""
Assuming this file is saved to a directory called 'utils' in a project called 'someproject',
add the following to project's setting.py:
ES_MAPPING_MODIFIER_CLASSES = ["someproject.utils.search_mapping_modifier.RelatedResourceEsMappingModifier"]
"""
from arches.app.search.es_mapping_modifier import EsMappingModifier
from arches.app.search.elasticsearch_dsl_builder import Bool, Match, Nested
from arches.app.models import models
class RelatedResourceEsMappingModifier(EsMappingModifier):
counter = 1
def __init__(self):
pass
@staticmethod
def add_search_terms(resourceinstance, document, terms):
if EsMappingModifier.get_mapping_property() not in document:
document[EsMappingModifier.get_mapping_property()] = []
first_hop = models.ResourceXResource.objects.filter(resourceinstanceidfrom=resourceinstance).values_list('resourceinstanceidto', flat=True)
second_hop = models.ResourceXResource.objects.filter(resourceinstanceidfrom__in=first_hop)
names = " ".join([str(relationship.resourceinstanceidto.name) for relationship in second_hop])
document[EsMappingModifier.get_mapping_property()].append(
{
"custom_value": names
}
)
RelatedResourceEsMappingModifier.counter = RelatedResourceEsMappingModifier.counter + 1
@staticmethod
def create_nested_custom_filter(term, original_element):
if "nested" not in original_element:
return original_element
document_key = EsMappingModifier.get_mapping_property()
custom_filter = Bool()
custom_filter.should(
Match(
field="%s.custom_value" % document_key,
query=term["value"],
type="phrase_prefix",
)
)
custom_filter.should(
Match(
field="%s.custom_value.folded" % document_key,
query=term["value"],
type="phrase_prefix",
)
)
nested_custom_filter = Nested(path=document_key, query=custom_filter)
new_must_element = Bool()
new_must_element.should(original_element)
new_must_element.should(nested_custom_filter)
new_must_element.dsl["bool"]["minimum_should_match"] = 1
return new_must_element
@staticmethod
def add_search_filter(search_query, term):
original_must_filter = search_query.dsl["bool"]["must"]
search_query.dsl["bool"]["must"] = []
for must_element in original_must_filter:
search_query.must(
RelatedResourceEsMappingModifier.create_nested_custom_filter(term, must_element)
)
original_must_filter = search_query.dsl["bool"]["must_not"]
search_query.dsl["bool"]["must_not"] = []
for must_element in original_must_filter:
search_query.must_not(
RelatedResourceEsMappingModifier.create_nested_custom_filter(term, must_element)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment