Skip to content

Commit a06e286

Browse files
Otis0408Otis0408
authored andcommitted
fix: DocumentCleaner wiped the middle page of a 3-page document
With remove_repeated_substrings=True, header/footer detection compares the pages between the first and last. For a 3-page document that slice is a single page, and _find_longest_common_ngram reduced set.intersection over that one page's ngrams to the page's own longest ngram, which was then removed from every page, wiping the unique middle page. Require at least two sequences before deriving a common ngram.
1 parent 9a01927 commit a06e286

3 files changed

Lines changed: 23 additions & 1 deletion

File tree

haystack/components/preprocessors/document_cleaner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ def _find_longest_common_ngram(self, sequences: list[str], min_ngram: int = 3, m
341341
:returns: The longest ngram that all sequences have in common.
342342
"""
343343
sequences = [s for s in sequences if s] # filter empty sequences
344-
if not sequences:
344+
if len(sequences) < 2:
345+
# a single sequence has no ngram "in common" with any other; treating
346+
# its own longest ngram as a repeated header/footer would wipe it
345347
return ""
346348
seqs_ngrams = map(partial(self._allngram, min_ngram=min_ngram, max_ngram=max_ngram), sequences)
347349
intersection = reduce(set.intersection, seqs_ngrams)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
fixes:
3+
- |
4+
Fixed ``DocumentCleaner`` wiping the middle page of a 3-page document when
5+
``remove_repeated_substrings=True``. Header/footer detection compares the
6+
pages between the first and last, which is a single page for a 3-page
7+
document; its own longest ngram was then treated as a repeated header/footer
8+
and removed. Detection now requires at least two pages to compare, so unique
9+
content is preserved while genuine repeated headers/footers are still removed.

test/components/preprocessors/test_document_cleaner.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ def test_remove_repeated_substrings(self):
121121
result = cleaner.run(documents=[Document(content=text)])
122122
assert result["documents"][0].content == expected_text
123123

124+
def test_remove_repeated_substrings_preserves_unique_middle_page(self):
125+
cleaner = DocumentCleaner(
126+
remove_empty_lines=False, remove_extra_whitespaces=False, remove_repeated_substrings=True
127+
)
128+
text = "PAGE ONE\fThe quick brown fox jumps high\fPAGE THREE"
129+
result = cleaner.run(documents=[Document(content=text)])["documents"][0]
130+
assert result.content.split("\f")[1] == "The quick brown fox jumps high"
131+
# With no genuine repeated header/footer, all three pages must round-trip unchanged and in order.
132+
assert result.content.split("\f") == ["PAGE ONE", "The quick brown fox jumps high", "PAGE THREE"]
133+
assert result.content == text
134+
124135
def test_copy_metadata(self):
125136
cleaner = DocumentCleaner()
126137
documents = [

0 commit comments

Comments
 (0)