@@ -19,6 +19,7 @@ import (
1919// Collection represents a named collection of vectors with a specific schema
2020type Collection struct {
2121 mu sync.RWMutex
22+ db * Database
2223 name string
2324 config * CollectionConfig
2425 index index.Index
@@ -798,6 +799,46 @@ func (c *Collection) DeleteBatch(ctx context.Context, ids []string) error {
798799 return nil
799800}
800801
802+ // Get returns a persisted record by ID.
803+ func (c * Collection ) Get (ctx context.Context , id string ) (Record , error ) {
804+ c .mu .RLock ()
805+ if c .closed {
806+ c .mu .RUnlock ()
807+ return Record {}, ErrCollectionClosed
808+ }
809+ c .mu .RUnlock ()
810+
811+ entry , err := c .storage .Get (ctx , id )
812+ if err != nil {
813+ return Record {}, fmt .Errorf ("%w: %s" , ErrRecordNotFound , id )
814+ }
815+ return recordFromIndexEntry (entry ), nil
816+ }
817+
818+ // UpdateIfVersion updates a record only if its current committed version matches expectedVersion.
819+ func (c * Collection ) UpdateIfVersion (ctx context.Context , id string , vector []float32 , metadata map [string ]interface {}, expectedVersion uint64 ) error {
820+ return c .withCAS (ctx , func (tx Tx ) error {
821+ return tx .UpdateIfVersion (ctx , c .name , id , vector , metadata , expectedVersion )
822+ })
823+ }
824+
825+ // DeleteIfVersion deletes a record only if its current committed version matches expectedVersion.
826+ func (c * Collection ) DeleteIfVersion (ctx context.Context , id string , expectedVersion uint64 ) error {
827+ return c .withCAS (ctx , func (tx Tx ) error {
828+ return tx .DeleteIfVersion (ctx , c .name , id , expectedVersion )
829+ })
830+ }
831+
832+ func (c * Collection ) withCAS (ctx context.Context , fn func (tx Tx ) error ) error {
833+ if c == nil {
834+ return ErrCollectionClosed
835+ }
836+ if c .db == nil {
837+ return ErrTxEngineUnsupported
838+ }
839+ return c .db .WithTx (ctx , fn )
840+ }
841+
801842// Iterate walks all persisted records in the collection.
802843func (c * Collection ) Iterate (ctx context.Context , fn func (Record ) error ) error {
803844 c .mu .RLock ()
@@ -923,8 +964,9 @@ func (c *Collection) Search(ctx context.Context, vector []float32, k int) (*Sear
923964 results := make ([]* SearchResult , len (indexResults ))
924965 for i , r := range indexResults {
925966 result := & SearchResult {
926- ID : r .ID ,
927- Score : r .Score ,
967+ ID : r .ID ,
968+ Score : r .Score ,
969+ Version : r .Version ,
928970 }
929971 if len (r .Vector ) > 0 {
930972 result .Vector = cloneVector (r .Vector )
@@ -941,10 +983,11 @@ func (c *Collection) Search(ctx context.Context, vector []float32, k int) (*Sear
941983 }
942984 }
943985 }
944- if result .Vector == nil || result .Metadata == nil {
986+ if result .Vector == nil || result .Metadata == nil || result . Version == 0 {
945987 entry , getErr := c .storage .Get (ctx , result .ID )
946988 if getErr == nil {
947989 result .ID = entry .ID
990+ result .Version = entry .Version
948991 if result .Vector == nil {
949992 result .Vector = cloneVector (entry .Vector )
950993 }
@@ -1502,6 +1545,7 @@ func (c *Collection) getAllVectors(ctx context.Context) ([]*index.VectorEntry, e
15021545 Ordinal : entry .Ordinal ,
15031546 Vector : make ([]float32 , len (entry .Vector )),
15041547 Metadata : make (map [string ]interface {}),
1548+ Version : entry .Version ,
15051549 }
15061550 copy (vectorCopy .Vector , entry .Vector )
15071551 for k , v := range entry .Metadata {
@@ -1527,6 +1571,7 @@ func recordFromIndexEntry(entry *index.VectorEntry) Record {
15271571 ID : entry .ID ,
15281572 Vector : cloneVector (entry .Vector ),
15291573 Metadata : cloneMetadata (entry .Metadata ),
1574+ Version : entry .Version ,
15301575 }
15311576}
15321577
0 commit comments