ไลบรารีการค้นหาเวกเตอร์ด้านไคลเอนต์ที่สามารถฝังค้นหาและแคช ทำงานบนเบราว์เซอร์และฝั่งเซิร์ฟเวอร์
มันมีประสิทธิภาพสูงกว่าการทำข้อความของ OpenAi-embedding-ADA-002 และเร็วกว่า Pinecone และ vectordbs อื่น ๆ
ฉันเป็นผู้ก่อตั้ง SearchBase.app และเราต้องการสิ่งนี้สำหรับผลิตภัณฑ์และลูกค้าของเรา เราจะใช้ห้องสมุดนี้ในการผลิต คุณสามารถมั่นใจได้ว่าจะได้รับการดูแลและปรับปรุง
การปรับปรุงมากมายกำลังจะมา!
เป้าหมายของเราคือการสร้างการค้นหาเวกเตอร์ที่รวดเร็วและรวดเร็วซึ่งทำงานกับเวกเตอร์สองร้อยถึงพัน ~ 1K เวกเตอร์ต่อผู้ใช้ครอบคลุม 99% ของกรณีการใช้งาน
ตอนแรกเราจะเก็บสิ่งต่าง ๆ ไว้ง่าย ๆ และย่อย 100ms
npm i client-vector-searchไลบรารีนี้มีโซลูชันปลั๊กแอนด์เพลย์สำหรับการฝังและการค้นหาเวกเตอร์ มันถูกออกแบบมาให้ใช้งานง่ายมีประสิทธิภาพและหลากหลาย นี่คือคู่มือเริ่มต้นอย่างรวดเร็ว:
import { getEmbedding , EmbeddingIndex } from 'client-vector-search' ;
// getEmbedding is an async function, so you need to use 'await' or '.then()' to get the result
const embedding = await getEmbedding ( "Apple" ) ; // Returns embedding as number[]
// Each object should have an 'embedding' property of type number[]
const initialObjects = [
{ id : 1 , name : "Apple" , embedding : embedding } ,
{ id : 2 , name : "Banana" , embedding : await getEmbedding ( "Banana" ) } ,
{ id : 3 , name : "Cheddar" , embedding : await getEmbedding ( "Cheddar" ) } ,
{ id : 4 , name : "Space" , embedding : await getEmbedding ( "Space" ) } ,
{ id : 5 , name : "database" , embedding : await getEmbedding ( "database" ) } ,
] ;
const index = new EmbeddingIndex ( initialObjects ) ; // Creates an index
// The query should be an embedding of type number[]
const queryEmbedding = await getEmbedding ( 'Fruit' ) ; // Query embedding
const results = await index . search ( queryEmbedding , { topK : 5 } ) ; // Returns top similar objects
// specify the storage type
await index . saveIndex ( 'indexedDB' ) ;
const results = await index . search ( [ 1 , 2 , 3 ] , {
topK : 5 ,
useStorage : 'indexedDB' ,
// storageOptions: { // use only if you overrode the defaults
// indexedDBName: 'clientVectorDB',
// indexedDBObjectStoreName: 'ClientEmbeddingStore',
// },
} ) ;
console . log ( results ) ;
await index . deleteIndexedDB ( ) ; // if you overrode default, specify db name หากต้องการใช้ภายในโครงการ NextJS คุณจะต้องอัปเดตไฟล์ next.config.js เพื่อรวมสิ่งต่อไปนี้:
module . exports = {
// Override the default webpack configuration
webpack : ( config ) => {
// See https://webpack.js.org/configuration/resolve/#resolvealias
config . resolve . alias = {
... config . resolve . alias ,
sharp$ : false ,
"onnxruntime-node$" : false ,
} ;
return config ;
} ,
} ; คุณสามารถเริ่มต้นโมเดลก่อนที่จะใช้เพื่อสร้าง embeddings สิ่งนี้จะช่วยให้มั่นใจได้ว่าโมเดลจะถูกโหลดก่อนที่จะใช้และให้ UX ที่ดีขึ้น
import { initializeModel } from "client-vector-search"
. . .
useEffect ( ( ) => {
try {
initializeModel ( ) ;
} catch ( e ) {
console . log ( e ) ;
}
} , [ ] ) ; คู่มือนี้ให้คำแนะนำทีละขั้นตอนของคุณสมบัติหลักของห้องสมุด มันครอบคลุมทุกอย่างตั้งแต่การสร้าง embeddings สำหรับสตริงไปจนถึงการดำเนินการในดัชนีเช่นการเพิ่มอัปเดตและการลบวัตถุ นอกจากนี้ยังมีคำแนะนำเกี่ยวกับวิธีการบันทึกดัชนีลงในฐานข้อมูลและดำเนินการค้นหาภายใน
จนกว่าเราจะมีเอกสารอ้างอิงคุณสามารถค้นหาวิธีการทั้งหมดและการใช้งานในคู่มือนี้ แต่ละขั้นตอนจะมาพร้อมกับตัวอย่างรหัสเพื่อแสดงการใช้วิธีที่เป็นปัญหา ตรวจสอบให้แน่ใจว่าได้ติดตามและลองตัวอย่างในสภาพแวดล้อมของคุณเองเพื่อให้เข้าใจได้ดีขึ้นว่าทุกอย่างทำงานอย่างไร
เริ่มต้นกันเถอะ!
สร้าง embeddings สำหรับสตริงที่กำหนดโดยใช้วิธี getEmbedding
const embedding = await getEmbedding ( "Apple" ) ; // Returns embedding as number[]หมายเหตุ :
getEmbeddingเป็นแบบอะซิงโครนัส; ตรวจสอบให้แน่ใจว่าใช้await
คำนวณความคล้ายคลึงกันของโคไซน์ระหว่างสองฝังตัว
const similarity = cosineSimilarity ( embedding1 , embedding2 , 6 ) ;หมายเหตุ : การฝังตัวทั้งสองควรมีความยาวเท่ากัน
สร้างดัชนีด้วยอาร์เรย์เริ่มต้นของวัตถุ แต่ละวัตถุจะต้องมีคุณสมบัติ 'ฝัง'
const initialObjects = [ ... ] ;
const index = new EmbeddingIndex ( initialObjects ) ;เพิ่มวัตถุในดัชนี
const objectToAdd = { id : 6 , name : 'Cat' , embedding : await getEmbedding ( 'Cat' ) } ;
index . add ( objectToAdd ) ;อัปเดตวัตถุที่มีอยู่ในดัชนี
const vectorToUpdate = { id : 6 , name : 'Dog' , embedding : await getEmbedding ( 'Dog' ) } ;
index . update ( { id : 6 } , vectorToUpdate ) ;ลบวัตถุออกจากดัชนี
index . remove ( { id : 6 } ) ;ดึงวัตถุจากดัชนี
const vector = index . get ( { id : 1 } ) ;ค้นหาดัชนีด้วยการฝังแบบสอบถาม
const queryEmbedding = await getEmbedding ( 'Fruit' ) ;
const results = await index . search ( queryEmbedding , { topK : 5 } ) ;พิมพ์ดัชนีทั้งหมดไปยังคอนโซล
index . printIndex ( ) ;บันทึกดัชนีลงในฐานข้อมูล indexedDB แบบถาวร บันทึก
await index . saveIndex ( "indexedDB" , { DBName : "clientVectorDB" , objectStoreName : "ClientEmbeddingStore" } )ดำเนินการค้นหาใน indexedDB
const results = await index . search ( queryEmbedding , {
topK : 5 ,
useStorage : "indexedDB" ,
storageOptions : { // only if you want to override the default options, defaults are below
indexedDBName : 'clientVectorDB' ,
indexedDBObjectStoreName : 'ClientEmbeddingStore'
}
} ) ;
-- -
### Delete Database
To delete an entire database .
`` ` ts
await IndexedDbManager . deleteIndexedDB ( "clientVectorDB" ) ;ในการลบอ็อบเจ็กต์จัดเก็บจากฐานข้อมูล
await IndexedDbManager . deleteIndexedDBObjectStore ( "clientVectorDB" , "ClientEmbeddingStore" ) ;เพื่อดึงวัตถุทั้งหมดจากที่เก็บวัตถุเฉพาะ
const allObjects = await IndexedDbManager . getAllObjectsFromIndexedDB ( "clientVectorDB" , "ClientEmbeddingStore" ) ;