nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: opensearch-project/opensearch-py
Pull request #771 (2024-07-09 00:14:46)

Fixed issue 769:Collapse not preserved when chaining a search instance
### Description
When clone method is called for search.filter(), collapse attribute was not copied. Therefore, collapse attribute wasn't getting chained to the search object. This fix adds copying the collapse attribute to the search object in the clone method. 

### Issues Resolved
Resolves #[769]

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check [here](https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin).


imvtsl: @saimedhi 
Please review.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d3e1115..33856463 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 ### Deprecated
 ### Removed
 ### Fixed
+- Fixed Search helper to ensure proper retention of the _collapse attribute in chained operations. ([#771](https://github.com/opensearch-project/opensearch-py/pull/771))
 ### Updated APIs
 - Updated opensearch-py APIs to reflect [opensearch-api-specification@7452827](https://github.com/opensearch-project/opensearch-api-specification/commit/745282767026703ea27967d2705633c3e2661c97)
 - Updated opensearch-py APIs to reflect [opensearch-api-specification@f2afd71](https://github.com/opensearch-project/opensearch-api-specification/commit/f2afd7171406c7477fbd644d74087bb0e2948c75)
diff --git a/opensearchpy/helpers/search.py b/opensearchpy/helpers/search.py
index 5693e916..aa157b10 100644
--- a/opensearchpy/helpers/search.py
+++ b/opensearchpy/helpers/search.py
@@ -431,6 +431,7 @@ class Search(Request):
         s._highlight_opts = self._highlight_opts.copy()
         s._suggest = self._suggest.copy()
         s._script_fields = self._script_fields.copy()
+        s._collapse = self._collapse.copy()
         for x in ("query", "post_filter"):
             getattr(s, x)._proxied = getattr(self, x)._proxied
 


Test patch:
diff --git a/test_opensearchpy/test_helpers/test_search.py b/test_opensearchpy/test_helpers/test_search.py
index c7fa20c5..4bb6cdb5 100644
--- a/test_opensearchpy/test_helpers/test_search.py
+++ b/test_opensearchpy/test_helpers/test_search.py
@@ -622,3 +622,19 @@ def test_rescore_query_to_dict() -> None:
             },
         },
     }
+
+
+def test_collapse_chaining() -> None:
+    s = search.Search(index="index_name")
+    s = s.filter("term", color="red")
+    s = s.collapse(field="category")
+    s = s.filter("term", brand="something")
+
+    assert {
+        "query": {
+            "bool": {
+                "filter": [{"term": {"color": "red"}}, {"term": {"brand": "something"}}]
+            }
+        },
+        "collapse": {"field": "category"},
+    } == s.to_dict()