[docs]classJaguar(VectorStore):"""`Jaguar API` vector store. See http://www.jaguardb.com See http://github.com/fserv/jaguar-sdk Example: .. code-block:: python from langchain_community.vectorstores.jaguar import Jaguar vectorstore = Jaguar( pod = 'vdb', store = 'mystore', vector_index = 'v', vector_type = 'cosine_fraction_float', vector_dimension = 1536, url='http://192.168.8.88:8080/fwww/', embedding=openai_model ) """
[docs]def__init__(self,pod:str,store:str,vector_index:str,vector_type:str,vector_dimension:int,url:str,embedding:Embeddings,):self._pod=podself._store=storeself._vector_index=vector_indexself._vector_type=vector_typeself._vector_dimension=vector_dimensionself._embedding=embeddingtry:fromjaguardb_http_client.JaguarHttpClientimportJaguarHttpClientexceptImportError:raiseImportError("Could not import jaguardb-http-client python package. ""Please install it with `pip install -U jaguardb-http-client`")self._jag=JaguarHttpClient(url)self._token=""
[docs]deflogin(self,jaguar_api_key:Optional[str]="",)->bool:""" login to jaguardb server with a jaguar_api_key or let self._jag find a key Args: pod (str): name of a Pod store (str): name of a vector store optional jaguar_api_key (str): API key of user to jaguardb server Returns: True if successful; False if not successful """ifjaguar_api_key=="":jaguar_api_key=self._jag.getApiKey()self._jaguar_api_key=jaguar_api_keyself._token=self._jag.login(jaguar_api_key)ifself._token=="":logger.error("E0001 error init(): invalid jaguar_api_key")returnFalsereturnTrue
[docs]defcreate(self,metadata_str:str,text_size:int,)->None:""" create the vector store on the backend database Args: metadata_str (str): columns and their types Returns: True if successful; False if not successful """podstore=self._pod+"."+self._store""" source column is required. v:text column is required. """q="create store "q+=podstoreq+=f" ({self._vector_index} vector({self._vector_dimension},"q+=f" '{self._vector_type}'),"q+=f" source char(256), v:text char({text_size}),"q+=metadata_str+")"self.run(q)
[docs]defrun(self,query:str,withFile:bool=False)->dict:""" Run any query statement in jaguardb Args: query (str): query statement to jaguardb Returns: None for invalid token, or json result string """ifself._token=="":logger.error(f"E0005 error run({query})")return{}resp=self._jag.post(query,self._token,withFile)txt=resp.texttry:js=json.loads(txt)returnjsexceptException:return{}
[docs]defadd_texts(# type: ignore[override]self,texts:List[str],metadatas:Optional[List[dict]]=None,**kwargs:Any,)->List[str]:""" Add texts through the embeddings and add to the vectorstore. Args: texts: list of text strings to add to the jaguar vector store. metadatas: Optional list of metadatas associated with the texts. [{"m1": "v11", "m2": "v12", "m3": "v13", "filecol": "path_file1.jpg" }, {"m1": "v21", "m2": "v22", "m3": "v23", "filecol": "path_file2.jpg" }, {"m1": "v31", "m2": "v32", "m3": "v33", "filecol": "path_file3.jpg" }, {"m1": "v41", "m2": "v42", "m3": "v43", "filecol": "path_file4.jpg" }] kwargs: vector_index=name_of_vector_index file_column=name_of_file_column Returns: List of ids from adding the texts into the vectorstore """vcol=self._vector_indexfilecol=kwargs.get("file_column","")text_tag=kwargs.get("text_tag","")podstorevcol=self._pod+"."+self._store+"."+vcolq="textcol "+podstorevcoljs=self.run(q)ifjs=="":return[]textcol=js["data"]iftext_tag!="":tag_texts=[]fortintexts:tag_texts.append(text_tag+" "+t)texts=tag_textsembeddings=self._embedding.embed_documents(list(texts))ids=[]ifmetadatasisNone:### no meta and no files to uploadi=0forvecinembeddings:str_vec=[str(x)forxinvec]values_comma=",".join(str_vec)podstore=self._pod+"."+self._storeq="insert into "+podstore+" ("q+=vcol+","+textcol+") values ('"+values_commatxt=texts[i].replace("'","\\'")q+="','"+txt+"')"js=self.run(q,False)ids.append(js["zid"])i+=1else:i=0forvecinembeddings:str_vec=[str(x)forxinvec]nvec,vvec,filepath=self._parseMeta(metadatas[i],filecol)iffilecol!="":rc=self._jag.postFile(self._token,filepath,1)ifnotrc:return[]names_comma=",".join(nvec)names_comma+=","+vcol## col1,col2,col3,veclvalues_comma="'"+"','".join(vvec)+"'"### 'va1','val2','val3'values_comma+=",'"+",".join(str_vec)+"'"### 'v1,v2,v3'podstore=self._pod+"."+self._storeq="insert into "+podstore+" ("q+=names_comma+","+textcol+") values ("+values_commatxt=texts[i].replace("'","\\'")q+=",'"+txt+"')"iffilecol!="":js=self.run(q,True)else:js=self.run(q,False)ids.append(js["zid"])i+=1returnids
[docs]defsimilarity_search_with_score(self,query:str,k:int=3,fetch_k:int=-1,where:Optional[str]=None,args:Optional[str]=None,metadatas:Optional[List[str]]=None,**kwargs:Any,)->List[Tuple[Document,float]]:""" Return Jaguar documents most similar to query, along with scores. Args: query: Text to look up documents similar to. k: Number of Documents to return. Defaults to 3. lambda_val: lexical match parameter for hybrid search. where: the where clause in select similarity. For example a where can be "rating > 3.0 and (state = 'NV' or state = 'CA')" args: extra options passed to select similarity kwargs: vector_index=vcol, vector_type=cosine_fraction_float Returns: List of Documents most similar to the query and score for each. List of Tuples of (doc, similarity_score): [ (doc, score), (doc, score), ...] """vcol=self._vector_indexvtype=self._vector_typeembeddings=self._embedding.embed_query(query)str_embeddings=[str(f)forfinembeddings]qv_comma=",".join(str_embeddings)podstore=self._pod+"."+self._storeq=("select similarity("+vcol+",'"+qv_comma+"','topk="+str(k)+",fetch_k="+str(fetch_k)+",type="+vtype)q+=",with_score=yes,with_text=yes"ifargsisnotNone:q+=","+argsifmetadatasisnotNone:meta="&".join(metadatas)q+=",metadata="+metaq+="') from "+podstoreifwhereisnotNone:q+=" where "+wherejarr=self.run(q)ifjarrisNone:return[]docs_with_score=[]forjsinjarr:score=js["score"]text=js["text"]zid=js["zid"]### give metadatasmd={}md["zid"]=zidifmetadatasisnotNone:forminmetadatas:mv=js[m]md[m]=mvdoc=Document(page_content=text,metadata=md)tup=(doc,score)docs_with_score.append(tup)returndocs_with_score
[docs]defsimilarity_search(self,query:str,k:int=3,where:Optional[str]=None,metadatas:Optional[List[str]]=None,**kwargs:Any,)->List[Document]:""" Return Jaguar documents most similar to query, along with scores. Args: query: Text to look up documents similar to. k: Number of Documents to return. Defaults to 5. where: the where clause in select similarity. For example a where can be "rating > 3.0 and (state = 'NV' or state = 'CA')" Returns: List of Documents most similar to the query """docs_and_scores=self.similarity_search_with_score(query,k=k,where=where,metadatas=metadatas,**kwargs)return[docfordoc,_indocs_and_scores]
[docs]defis_anomalous(self,query:str,**kwargs:Any,)->bool:""" Detect if given text is anomalous from the dataset Args: query: Text to detect if it is anomaly Returns: True or False """vcol=self._vector_indexvtype=self._vector_typeembeddings=self._embedding.embed_query(query)str_embeddings=[str(f)forfinembeddings]qv_comma=",".join(str_embeddings)podstore=self._pod+"."+self._storeq="select anomalous("+vcol+", '"+qv_comma+"', 'type="+vtype+"')"q+=" from "+podstorejs=self.run(q)ifisinstance(js,list)andlen(js)==0:returnFalsejd=json.loads(js[0])ifjd["anomalous"]=="YES":returnTruereturnFalse
[docs]defclear(self)->None:""" Delete all records in jaguardb Args: No args Returns: None """podstore=self._pod+"."+self._storeq="truncate store "+podstoreself.run(q)
[docs]defdelete(self,zids:List[str],**kwargs:Any)->None:# type: ignore[override]""" Delete records in jaguardb by a list of zero-ids Args: pod (str): name of a Pod ids (List[str]): a list of zid as string Returns: Do not return anything """podstore=self._pod+"."+self._storeforzidinzids:q="delete from "+podstore+" where zid='"+zid+"'"self.run(q)
[docs]defcount(self)->int:""" Count records of a store in jaguardb Args: no args Returns: (int) number of records in pod store """podstore=self._pod+"."+self._storeq="select count() from "+podstorejs=self.run(q)ifisinstance(js,list)andlen(js)==0:return0jd=json.loads(js[0])returnint(jd["data"])
[docs]defdrop(self)->None:""" Drop or remove a store in jaguardb Args: no args Returns: None """podstore=self._pod+"."+self._storeq="drop store "+podstoreself.run(q)
[docs]deflogout(self)->None:""" Logout to cleanup resources Args: no args Returns: None """self._jag.logout(self._token)