diff --git a/HISTORY.rst b/HISTORY.rst index 0412ef9235..a97e71cd97 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -9,7 +9,8 @@ XX (2017-XX-XX) - Make tags, metadata types and cabinets searchable via the dynamic search API. GitLab issue #344. - Add support for updating configuration options from environment variables. - Add purgelocks management command. GitLab issue #221. - +- Fix index rebuilding for multi value first levels. GitLab issue #391. + 2.3 (2017-06-08) ================ - Allow for bigger indexing expression templates. diff --git a/mayan/apps/document_indexing/models.py b/mayan/apps/document_indexing/models.py index 1fa15ef6b8..557fd33c74 100644 --- a/mayan/apps/document_indexing/models.py +++ b/mayan/apps/document_indexing/models.py @@ -179,8 +179,8 @@ class IndexTemplateNode(MPTTModel): else: return self.expression - def index_document(self, document, acquire_lock=True): - # Avoid another process to index this same document for the same + def index_document(self, document, acquire_lock=True, index_instance_node_parent=None): + # Avoid another process indexing this same document for the same # template node. This prevents this template node's index instance # nodes from being deleted while the template is evaluated and # documents added to it. @@ -211,16 +211,20 @@ class IndexTemplateNode(MPTTModel): index_instance_node, created = self.index_instance_nodes.get_or_create() for child in self.get_children(): - child.index_document(document=document, acquire_lock=False) + child.index_document( + document=document, acquire_lock=False, + index_instance_node_parent=index_instance_node + ) if acquire_lock: lock.release() elif self.enabled: logger.debug('IndexTemplateNode; non parent: evaluating') - logger.debug('My parent is: %s', self.parent) + logger.debug('My parent template is: %s', self.parent) logger.debug( - 'My parent nodes: %s', self.parent.index_instance_nodes.all() + 'My parent instance node is: %s', + index_instance_node_parent ) logger.debug( 'IndexTemplateNode; Evaluating template: %s', self.expression @@ -245,14 +249,17 @@ class IndexTemplateNode(MPTTModel): logger.debug('Evaluation result: %s', result) if result: index_instance_node, created = self.index_instance_nodes.get_or_create( - parent=self.parent.index_instance_nodes.get(), + parent=index_instance_node_parent, value=result ) if self.link_documents: index_instance_node.documents.add(document) for child in self.get_children(): - child.index_document(document=document, acquire_lock=False) + child.index_document( + document=document, acquire_lock=False, + index_instance_node_parent=index_instance_node + ) finally: if acquire_lock: lock.release() diff --git a/mayan/apps/document_indexing/tests/test_models.py b/mayan/apps/document_indexing/tests/test_models.py index dfc3831e02..f1706981d9 100644 --- a/mayan/apps/document_indexing/tests/test_models.py +++ b/mayan/apps/document_indexing/tests/test_models.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from django.test import override_settings +from django.utils.encoding import force_text from common.tests import BaseTestCase from documents.models import DocumentType @@ -169,3 +170,42 @@ class IndexTestCase(BaseTestCase): self.assertQuerysetEqual( instance_node.documents.all(), [repr(self.document)] ) + + def test_dual_level_dual_document_index(self): + """ + Test creation of an index instance with two first levels with different + values and two second levels with the same value but as separate + children of each of the first levels. + """ + with open(TEST_SMALL_DOCUMENT_PATH) as file_object: + self.document_2 = self.document_type.new_document( + file_object=file_object + ) + + # Create empty index + index = Index.objects.create(label=TEST_INDEX_LABEL) + + # Add our document type to the new index + index.document_types.add(self.document_type) + + # Create simple index template + root = index.template_root + level_1 = index.node_templates.create( + parent=root, expression='{{ document.uuid }}', + link_documents=False + ) + + index.node_templates.create( + parent=level_1, expression='{{ document.label }}', + link_documents=True + ) + + Index.objects.rebuild() + + self.assertEqual( + [instance.value for instance in IndexInstanceNode.objects.all()], + [ + '', force_text(self.document_2.uuid), self.document_2.label, + force_text(self.document.uuid), self.document.label + ] + )