faiss-haystack 3.0.0__tar.gz → 3.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/faiss-v3.0.0] - 2026-10-16
4
+
5
+ ### 🧪 Testing
6
+
7
+ - Use Python 3.11 in tests instead of 3.10 (#4103)
8
+ - Test compatible integrations with Python 3.15; update pyproject (#4104)
9
+
10
+ ### ⚙️ CI
11
+
12
+ - Improve changelog generation; fix existing changelogs (#3883)
13
+
14
+ ### 🧹 Chores
15
+
16
+ - Switch remaining document stores to haystack.logging (#4011)
17
+ - [**breaking**] Drop Python 3.10 support (#4105)
18
+
19
+
3
20
  ## [integrations/faiss-v2.1.0] - 2026-09-01
4
21
 
5
22
  ### 🐛 Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: faiss-haystack
3
- Version: 3.0.0
3
+ Version: 3.0.1
4
4
  Summary: An integration of FAISS (library for efficient similarity search of dense vectors) with Haystack
5
5
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/faiss#readme
6
6
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
@@ -152,9 +152,9 @@ class FAISSDocumentStore:
152
152
  msg = f"Document with id '{doc.id}' already exists."
153
153
  raise DuplicateDocumentError(msg)
154
154
 
155
- # Process documents
156
- ids_to_add_to_index = []
157
- vectors_to_add = []
155
+ # Process documents. Pending vectors are keyed by document ID so that a later duplicate in the same
156
+ # batch replaces the earlier one instead of leaving an orphaned vector in the FAISS index.
157
+ pending_vectors: dict[str, tuple[int, list[float]]] = {}
158
158
 
159
159
  docs_written = 0
160
160
 
@@ -168,6 +168,7 @@ class FAISSDocumentStore:
168
168
  # FAISS doesn't support easy update. We'd have to remove and add.
169
169
  # For MVP, let's implement remove then add for overwrite.
170
170
  self.delete_documents([doc.id])
171
+ pending_vectors.pop(doc.id, None)
171
172
 
172
173
  self.documents[doc.id] = doc
173
174
 
@@ -179,15 +180,14 @@ class FAISSDocumentStore:
179
180
  self.id_map[int_id] = doc.id
180
181
  self.inverse_id_map[doc.id] = int_id
181
182
 
182
- ids_to_add_to_index.append(int_id)
183
- vectors_to_add.append(doc.embedding)
183
+ pending_vectors[doc.id] = (int_id, doc.embedding)
184
184
 
185
185
  docs_written += 1
186
186
 
187
187
  # Add to FAISS
188
- if vectors_to_add:
189
- vectors = np.array(vectors_to_add, dtype="float32")
190
- ids = np.array(ids_to_add_to_index, dtype="int64")
188
+ if pending_vectors:
189
+ vectors = np.array([vector for _, vector in pending_vectors.values()], dtype="float32")
190
+ ids = np.array([int_id for int_id, _ in pending_vectors.values()], dtype="int64")
191
191
  index = self._get_index_or_raise()
192
192
  index.add_with_ids(vectors, ids)
193
193
 
@@ -55,6 +55,21 @@ class TestFAISSDocumentStoreUnit:
55
55
  with pytest.raises(DuplicateDocumentError, match="already exists"):
56
56
  ds.write_documents([Document(id="dup", content="second")], policy=DuplicatePolicy.FAIL)
57
57
 
58
+ def test_write_documents_overwrite_duplicate_in_same_batch_leaves_no_orphan_vector(self):
59
+ ds = FAISSDocumentStore(embedding_dim=2)
60
+ docs = [
61
+ Document(id="a", content="old", embedding=[0.0, 0.0]),
62
+ Document(id="a", content="new", embedding=[0.1, 0.1]),
63
+ Document(id="b", content="b", embedding=[5.0, 5.0]),
64
+ ]
65
+ ds.write_documents(docs, policy=DuplicatePolicy.OVERWRITE)
66
+
67
+ assert ds.count_documents() == 2
68
+ assert ds.index.ntotal == 2
69
+ results = ds.search([0.0, 0.0], top_k=2)
70
+ assert [doc.id for doc in results] == ["a", "b"]
71
+ assert results[0].content == "new"
72
+
58
73
  @pytest.mark.parametrize(
59
74
  ("filters", "error_match"),
60
75
  [
File without changes