@@ -145,3 +145,89 @@ async def test_qdrant_register_and_unregister_vector_db(
145
145
await qdrant_adapter .unregister_vector_db (vector_db_id )
146
146
assert not (await qdrant_adapter .client .collection_exists (vector_db_id ))
147
147
assert len ((await qdrant_adapter .client .get_collections ()).collections ) == 0
148
+
149
+
150
+ # Keyword search tests
151
+ async def test_query_chunks_keyword_search (qdrant_vec_index , sample_chunks , sample_embeddings ):
152
+ """Test keyword search functionality in Qdrant."""
153
+ await qdrant_vec_index .add_chunks (sample_chunks , sample_embeddings )
154
+ query_string = "Sentence 5"
155
+ response = await qdrant_vec_index .query_keyword (query_string = query_string , k = 3 , score_threshold = 0.0 )
156
+
157
+ assert isinstance (response , QueryChunksResponse )
158
+ assert len (response .chunks ) > 0 , f"Expected some chunks, but got { len (response .chunks )} "
159
+
160
+ non_existent_query_str = "blablabla"
161
+ response_no_results = await qdrant_vec_index .query_keyword (
162
+ query_string = non_existent_query_str , k = 1 , score_threshold = 0.0
163
+ )
164
+
165
+ assert isinstance (response_no_results , QueryChunksResponse )
166
+ assert len (response_no_results .chunks ) == 0 , f"Expected 0 results, but got { len (response_no_results .chunks )} "
167
+
168
+
169
+ async def test_query_chunks_keyword_search_k_greater_than_results (qdrant_vec_index , sample_chunks , sample_embeddings ):
170
+ """Test keyword search when k is greater than available results."""
171
+ await qdrant_vec_index .add_chunks (sample_chunks , sample_embeddings )
172
+
173
+ query_str = "Sentence 1 from document 0" # Should match only one chunk
174
+ response = await qdrant_vec_index .query_keyword (k = 5 , score_threshold = 0.0 , query_string = query_str )
175
+
176
+ assert isinstance (response , QueryChunksResponse )
177
+ assert 0 < len (response .chunks ) < 5 , f"Expected results between [1, 4], got { len (response .chunks )} "
178
+ assert any ("Sentence 1 from document 0" in chunk .content for chunk in response .chunks ), "Expected chunk not found"
179
+
180
+
181
+ async def test_query_chunks_keyword_search_score_threshold (qdrant_vec_index , sample_chunks , sample_embeddings ):
182
+ """Test keyword search with score threshold filtering."""
183
+ await qdrant_vec_index .add_chunks (sample_chunks , sample_embeddings )
184
+
185
+ query_string = "Sentence 5"
186
+
187
+ # Test with low threshold (should return results)
188
+ response_low_threshold = await qdrant_vec_index .query_keyword (query_string = query_string , k = 3 , score_threshold = 0.0 )
189
+ assert len (response_low_threshold .chunks ) > 0
190
+
191
+ # Test with negative threshold (should return results since scores are 0.0)
192
+ response_negative_threshold = await qdrant_vec_index .query_keyword (
193
+ query_string = query_string , k = 3 , score_threshold = - 1.0
194
+ )
195
+ assert len (response_negative_threshold .chunks ) > 0
196
+
197
+
198
+ async def test_query_chunks_keyword_search_edge_cases (qdrant_vec_index , sample_chunks , sample_embeddings ):
199
+ """Test keyword search edge cases."""
200
+ await qdrant_vec_index .add_chunks (sample_chunks , sample_embeddings )
201
+
202
+ # Test with empty string
203
+ response_empty = await qdrant_vec_index .query_keyword (query_string = "" , k = 3 , score_threshold = 0.0 )
204
+ assert isinstance (response_empty , QueryChunksResponse )
205
+
206
+ # Test with very long query string
207
+ long_query = "a" * 1000
208
+ response_long = await qdrant_vec_index .query_keyword (query_string = long_query , k = 3 , score_threshold = 0.0 )
209
+ assert isinstance (response_long , QueryChunksResponse )
210
+
211
+ # Test with special characters
212
+ special_query = "!@#$%^&*()_+-=[]{}|;':\" ,./<>?"
213
+ response_special = await qdrant_vec_index .query_keyword (query_string = special_query , k = 3 , score_threshold = 0.0 )
214
+ assert isinstance (response_special , QueryChunksResponse )
215
+
216
+
217
+ async def test_query_chunks_keyword_search_metadata_preservation (
218
+ qdrant_vec_index , sample_chunks_with_metadata , sample_embeddings_with_metadata
219
+ ):
220
+ """Test that keyword search preserves chunk metadata."""
221
+ await qdrant_vec_index .add_chunks (sample_chunks_with_metadata , sample_embeddings_with_metadata )
222
+
223
+ query_string = "Sentence 0"
224
+ response = await qdrant_vec_index .query_keyword (query_string = query_string , k = 2 , score_threshold = 0.0 )
225
+
226
+ assert len (response .chunks ) > 0
227
+ for chunk in response .chunks :
228
+ # Check that metadata is preserved
229
+ assert hasattr (chunk , "metadata" ) or hasattr (chunk , "chunk_metadata" )
230
+ if hasattr (chunk , "chunk_metadata" ) and chunk .chunk_metadata :
231
+ assert chunk .chunk_metadata .document_id is not None
232
+ assert chunk .chunk_metadata .chunk_id is not None
233
+ assert chunk .chunk_metadata .source is not None
0 commit comments