1+ from datetime import timedelta
12from typing import List
23
34from ravendb import AbstractIndexCreationTask
5+ from ravendb .documents .indexes .definitions import SearchEngineType
46from ravendb .documents .indexes .vector .embedding import VectorEmbeddingType
57from ravendb .documents .indexes .vector .options import VectorOptions
8+ from ravendb .documents .operations .server_misc import ToggleDatabasesStateOperation
69from ravendb .tests .test_base import TestBase
710
811
912class Dto :
1013 def __init__ (
1114 self ,
12- embedding_base_64 : str ,
13- embedding_singles : List [float ],
14- embedding_sbytes : List [int ],
15- embedding_binary : List [int ],
15+ embedding_base_64 : str = None ,
16+ embedding_singles : List [float ] = None ,
17+ embedding_sbytes : List [int ] = None ,
18+ embedding_binary : List [int ] = None ,
1619 ):
1720 self .embedding_base_64 = embedding_base_64
1821 self .embedding_singles = embedding_singles
@@ -24,7 +27,7 @@ class DummyIndex(AbstractIndexCreationTask):
2427 def __init__ (self ):
2528 super ().__init__ ()
2629 self .map = """
27- from dto in docs.Dtos
30+ from dto in docs.Dtoes
2831 select new
2932 {
3033 Singles = CreateVector(dto.embedding_singles),
@@ -34,13 +37,14 @@ def __init__(self):
3437 """
3538 self ._vector ("Integers" , VectorOptions (VectorEmbeddingType .INT8 ))
3639 self ._vector ("Binary" , VectorOptions (VectorEmbeddingType .BINARY ))
40+ self .search_engine_type = SearchEngineType .CORAX
3741
3842
3943class IndexWithSetDimensions (AbstractIndexCreationTask ):
4044 def __init__ (self ):
4145 super ().__init__ ()
4246 self .map = """
43- from dto in docs.Dtos
47+ from dto in docs.Dtoes
4448 select new
4549 {
4650 Singles = CreateVector(dto.embedding_singles)
@@ -53,7 +57,7 @@ class IndexWithSetDimensionsInt8(AbstractIndexCreationTask):
5357 def __init__ (self ):
5458 super ().__init__ ()
5559 self .map = """
56- from dto in docs.Dtos
60+ from dto in docs.Dtoes
5761 select new
5862 {
5963 Sbytes = CreateVector(dto.embedding_singles)
@@ -91,7 +95,7 @@ def test_rql_generation(self):
9195 q7 = session .query (object_type = Dto ).vector_search_text_i8 ("TextField" , "aaaa" )
9296 self .assertEqual ("from 'Dtoes' where vector.search(embedding.text_i8(TextField), $p0)" , q7 ._to_string ())
9397
94- def test_rql_generation_async (self ):
98+ def test_rql_generation_2 (self ):
9599 with self .store .open_session () as session :
96100
97101 # -- Not applicable for Python - here we just don't have such methods in the API, making this impossible --
@@ -137,3 +141,53 @@ def test_rql_generation_async(self):
137141 "EmbeddingBase64" , "abcd==" , is_exact = True , number_of_candidates = 25
138142 )
139143 self .assertEqual ("from 'Dtoes' where exact(vector.search(EmbeddingBase64, $p0, null, 25))" , q8 ._to_string ())
144+
145+ def test_embedding_dimensions_check (self ):
146+ with self .store .open_session () as session :
147+ dto1 = Dto (embedding_singles = [0.5 , - 1.0 ])
148+ dto2 = Dto (embedding_singles = [0.2 , 0.3 ])
149+
150+ session .store (dto1 )
151+ session .store (dto2 )
152+
153+ session .save_changes ()
154+
155+ index = DummyIndex ()
156+
157+ index .execute (self .store )
158+
159+ self .wait_for_indexing (self .store )
160+
161+ database_disable_result = self .store .maintenance .server .send (
162+ ToggleDatabasesStateOperation (self .store .database , True )
163+ )
164+
165+ self .assertTrue (database_disable_result .success )
166+ self .assertTrue (database_disable_result .disabled )
167+ self .assertEqual (database_disable_result .name , self .store .database )
168+
169+ database_enable_result = self .store .maintenance .server .send (
170+ ToggleDatabasesStateOperation (self .store .database , False )
171+ )
172+
173+ self .assertTrue (database_enable_result .success )
174+ self .assertFalse (database_enable_result .disabled )
175+ self .assertEqual (database_enable_result .name , self .store .database )
176+
177+ dto3 = Dto (embedding_singles = [0.1 , 0.2 ])
178+ session .store (dto3 )
179+ session .save_changes ()
180+
181+ self .wait_for_indexing (self .store )
182+
183+ dto4 = Dto (embedding_singles = [0.5 , 0.7 , 0.9 ])
184+ session .store (dto4 )
185+ session .save_changes ()
186+
187+ index_errors = self .wait_for_indexing_errors (self .store , timeout = timedelta (seconds = 5 ))
188+
189+ self .assertEqual (1 , len (index_errors ))
190+ self .assertIn (
191+ "Attempted to index embedding with 3 dimensions, but field Singles already contains indexed embedding with 2 dimensions, or was explicitly configured for embeddings with 2 dimensions." ,
192+ index_errors [0 ].errors [0 ].error ,
193+ )
0 commit comments