@@ -93,7 +93,6 @@ def build_from_config(config: Dict[str, Any]) -> "RecordingSearchEmbeddingFuncti
9393 return RecordingSearchEmbeddingFunction (config .get ("label" , "default" ))
9494
9595
96- @pytest .mark .skipif (is_spann_disabled_mode , reason = skip_reason_spann_disabled )
9796def test_schema_spann_vector_config_persistence (
9897 client_factories : "ClientFactories" ,
9998) -> None :
@@ -135,29 +134,46 @@ def test_schema_spann_vector_config_persistence(
135134 assert vector_index is not None
136135 assert vector_index .enabled is True
137136 assert vector_index .config is not None
138- assert vector_index .config .spann is not None
139- spann_config = vector_index .config .spann
140- assert spann_config .search_nprobe == 16
141- assert spann_config .write_nprobe == 32
142- assert spann_config .ef_construction == 120
143- assert spann_config .max_neighbors == 24
137+
138+ if not is_spann_disabled_mode :
139+ assert vector_index .config .spann is not None
140+ spann_config = vector_index .config .spann
141+ assert spann_config .search_nprobe == 16
142+ assert spann_config .write_nprobe == 32
143+ assert spann_config .ef_construction == 120
144+ assert spann_config .max_neighbors == 24
145+ else :
146+ assert vector_index .config .spann is None
147+ assert vector_index .config .hnsw is not None
148+ hnsw_config = vector_index .config .hnsw
149+ assert hnsw_config .ef_construction == 100
150+ assert hnsw_config .ef_search == 100
151+ assert hnsw_config .max_neighbors == 16
152+ assert hnsw_config .resize_factor == 1.2
144153
145154 ef = vector_index .config .embedding_function
146155 assert ef is not None
147156 assert ef .name () == "simple_ef"
148157 assert ef .get_config () == {"dim" : 6 }
149158
150159 persisted_json = persisted_schema .serialize_to_json ()
151- spann_json = persisted_json ["keys" ]["#embedding" ]["float_list" ]["vector_index" ][
152- "config"
153- ]["spann" ]
154- assert spann_json ["search_nprobe" ] == 16
155- assert spann_json ["write_nprobe" ] == 32
160+ if not is_spann_disabled_mode :
161+ spann_json = persisted_json ["keys" ]["#embedding" ]["float_list" ]["vector_index" ][
162+ "config"
163+ ]["spann" ]
164+ assert spann_json ["search_nprobe" ] == 16
165+ assert spann_json ["write_nprobe" ] == 32
166+ else :
167+ hnsw_json = persisted_json ["keys" ]["#embedding" ]["float_list" ]["vector_index" ][
168+ "config"
169+ ]["hnsw" ]
170+ assert hnsw_json ["ef_construction" ] == 100
171+ assert hnsw_json ["ef_search" ] == 100
172+ assert hnsw_json ["max_neighbors" ] == 16
156173
157174 client_reloaded = client_factories .create_client_from_system ()
158175 reloaded_collection = client_reloaded .get_collection (
159176 name = collection_name ,
160- embedding_function = SimpleEmbeddingFunction (dim = 6 ), # type: ignore[arg-type]
161177 )
162178
163179 reloaded_schema = reloaded_collection .schema
@@ -167,9 +183,23 @@ def test_schema_spann_vector_config_persistence(
167183 reloaded_vector_index = reloaded_embedding_override .vector_index
168184 assert reloaded_vector_index is not None
169185 assert reloaded_vector_index .config is not None
170- assert reloaded_vector_index .config .spann is not None
171- assert reloaded_vector_index .config .spann .search_nprobe == 16
172- assert reloaded_vector_index .config .spann .write_nprobe == 32
186+ if not is_spann_disabled_mode :
187+ assert reloaded_vector_index .config .spann is not None
188+ assert reloaded_vector_index .config .spann .search_nprobe == 16
189+ assert reloaded_vector_index .config .spann .write_nprobe == 32
190+ else :
191+ assert reloaded_vector_index .config .hnsw is not None
192+ assert reloaded_vector_index .config .hnsw .ef_construction == 100
193+ assert reloaded_vector_index .config .hnsw .ef_search == 100
194+ assert reloaded_vector_index .config .hnsw .max_neighbors == 16
195+ assert reloaded_vector_index .config .hnsw .resize_factor == 1.2
196+
197+ config = reloaded_collection .configuration
198+ assert config is not None
199+ config_ef = config .get ("embedding_function" )
200+ assert config_ef is not None
201+ assert config_ef .name () == "simple_ef"
202+ assert config_ef .get_config () == {"dim" : 6 }
173203
174204
175205@register_sparse_embedding_function
@@ -650,6 +680,52 @@ def test_schema_delete_index_and_restore(
650680 assert set (search ["ids" ]) == {"key-enabled" }
651681
652682
683+ def test_disabled_metadata_index_filters_raise_invalid_argument_all_modes (
684+ client_factories : "ClientFactories" ,
685+ ) -> None :
686+ """Disabled metadata inverted index should block filter-based operations in get, query, and delete for local, single node, and distributed."""
687+ schema = Schema ().delete_index (
688+ key = "restricted_tag" , config = StringInvertedIndexConfig ()
689+ )
690+ collection , _ = _create_isolated_collection (client_factories , schema = schema )
691+
692+ collection .add (
693+ ids = ["restricted-doc" ],
694+ embeddings = cast (Embeddings , [[0.1 , 0.2 , 0.3 , 0.4 ]]),
695+ metadatas = [{"restricted_tag" : "blocked" }],
696+ documents = ["doc" ],
697+ )
698+
699+ assert collection .schema is not None
700+ schema_entry = collection .schema .keys ["restricted_tag" ].string
701+ assert schema_entry is not None
702+ index_config = schema_entry .string_inverted_index
703+ assert index_config is not None
704+ assert index_config .enabled is False
705+
706+ filter_payload : Dict [str , Any ] = {"restricted_tag" : "blocked" }
707+
708+ def _expect_disabled_error (operation : Callable [[], Any ]) -> None :
709+ with pytest .raises (InvalidArgumentError ) as exc_info :
710+ operation ()
711+ assert "Cannot filter using metadata key 'restricted_tag'" in str (
712+ exc_info .value
713+ )
714+
715+ operations : List [Callable [[], Any ]] = [
716+ lambda : collection .get (where = filter_payload ),
717+ lambda : collection .query (
718+ query_embeddings = cast (Embeddings , [[0.1 , 0.2 , 0.3 , 0.4 ]]),
719+ n_results = 1 ,
720+ where = filter_payload ,
721+ ),
722+ lambda : collection .delete (where = filter_payload ),
723+ ]
724+
725+ for operation in operations :
726+ _expect_disabled_error (operation )
727+
728+
653729@pytest .mark .skipif (is_spann_disabled_mode , reason = skip_reason_spann_disabled )
654730def test_disabled_metadata_index_filters_raise_invalid_argument (
655731 client_factories : "ClientFactories" ,
0 commit comments