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