base.py
1 """ 2 ANN (Approximate Nearest Neighbor) module 3 """ 4 5 import datetime 6 import platform 7 8 from ..version import __version__ 9 10 11 class ANN: 12 """ 13 Base class for ANN instances. This class builds vector indexes to support similarity search. 14 The built-in ANN backends store ids and vectors. Content storage is supported via database instances. 15 """ 16 17 def __init__(self, config): 18 """ 19 Creates a new ANN. 20 21 Args: 22 config: index configuration parameters 23 """ 24 25 # ANN index 26 self.backend = None 27 28 # ANN configuration 29 self.config = config 30 31 def load(self, path): 32 """ 33 Loads an ANN at path. 34 35 Args: 36 path: path to load ann index 37 """ 38 39 raise NotImplementedError 40 41 def index(self, embeddings): 42 """ 43 Builds an ANN index. 44 45 Args: 46 embeddings: embeddings array 47 """ 48 49 raise NotImplementedError 50 51 def append(self, embeddings): 52 """ 53 Append elements to an existing index. 54 55 Args: 56 embeddings: embeddings array 57 """ 58 59 raise NotImplementedError 60 61 def delete(self, ids): 62 """ 63 Deletes elements from existing index. 64 65 Args: 66 ids: ids to delete 67 """ 68 69 raise NotImplementedError 70 71 def search(self, queries, limit): 72 """ 73 Searches ANN index for query. Returns topn results. 74 75 Args: 76 queries: queries array 77 limit: maximum results 78 79 Returns: 80 query results 81 """ 82 83 raise NotImplementedError 84 85 def count(self): 86 """ 87 Number of elements in the ANN index. 88 89 Returns: 90 count 91 """ 92 93 raise NotImplementedError 94 95 def save(self, path): 96 """ 97 Saves an ANN index at path. 98 99 Args: 100 path: path to save ann index 101 """ 102 103 raise NotImplementedError 104 105 def close(self): 106 """ 107 Closes this ANN. 108 """ 109 110 self.backend = None 111 112 def setting(self, name, default=None): 113 """ 114 Looks up backend specific setting. 115 116 Args: 117 name: setting name 118 default: default value when setting not found 119 120 Returns: 121 setting value 122 """ 123 124 # Get the backend-specific config object 125 backend = self.config.get(self.config["backend"]) 126 127 # Get setting value, set default value if not found 128 setting = backend.get(name) if backend else None 129 return setting if setting or (backend and name in backend) else default 130 131 def metadata(self, settings=None): 132 """ 133 Adds index build metadata. 134 135 Args: 136 settings: index build settings 137 """ 138 139 # ISO 8601 timestamp 140 create = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") 141 142 # Set build metadata if this is not an update 143 if settings: 144 self.config["build"] = { 145 "create": create, 146 "python": platform.python_version(), 147 "settings": settings, 148 "system": f"{platform.system()} ({platform.machine()})", 149 "txtai": __version__, 150 } 151 152 # Set last update date 153 self.config["update"] = create