diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index abbce03c9a60f58fb42f1eb5f9893a2216c7caea..275869e62bdf8e09605d19cc98190644451493e0 100644 --- a/arkindex/documents/api/elements.py +++ b/arkindex/documents/api/elements.py @@ -1180,6 +1180,8 @@ class ElementBulkCreate(CreateAPIView): .objects .using('default') .filter( + # Using __overlap before __last makes Postgres use the GIN index instead of scanning the whole table + path__overlap=[self.element.id], path__last=self.element.id, element__type_id__in=set(element_data['type'] for element_data in elements) ) diff --git a/arkindex/documents/api/iiif.py b/arkindex/documents/api/iiif.py index 3fdc5d99b7a48f9dd266d7327540ae5532490f02..e40e16065ffe810c9140e39e8cae29b989d57df1 100644 --- a/arkindex/documents/api/iiif.py +++ b/arkindex/documents/api/iiif.py @@ -97,6 +97,7 @@ class TranscriptionSearchAnnotationList(SearchAPIMixin, RetrieveAPIView): element=list( Element.objects .filter( + paths__path__overlap=[self.get_element().id], paths__path__last=self.get_element().id, type__folder=False, zone__isnull=False, diff --git a/arkindex/documents/api/ml.py b/arkindex/documents/api/ml.py index 059e7c31d6087143a21f0ced718b481af8961848..cf67154b453a5e62ca268b778974f325b6bc1340 100644 --- a/arkindex/documents/api/ml.py +++ b/arkindex/documents/api/ml.py @@ -246,6 +246,7 @@ class ElementTranscriptionsBulk(CreateAPIView): .filter( zone__image_id=image_id, type=elt_type, + paths__path__overlap=[self.element.id], paths__path__last=self.element.id ) .only('id', 'zone_id') diff --git a/arkindex/documents/models.py b/arkindex/documents/models.py index bf9206602c68750874304ceb44869e103c87ef12..8a55a92c952607ecb6ac0ceebe2214feb20ddc48 100644 --- a/arkindex/documents/models.py +++ b/arkindex/documents/models.py @@ -202,12 +202,13 @@ class Element(IndexableModel): def get_next_order(self, type): """ Find the next ordering for a new child in ElementPath - Uses the primary database to avoid stale reads and duplicate orderings + Uses the primary database to avoid stale reads and duplicate orderings, + and path__overlap to let Postgres use the GIN index before filtering by last item. """ assert isinstance(type, ElementType) return ElementPath.objects \ .using('default') \ - .filter(path__last=self.id, element__type=type) \ + .filter(path__overlap=[self.id], path__last=self.id, element__type=type) \ .aggregate(max=models.Max('ordering') + 1)['max'] or 0 @transaction.atomic