Skip to content

Commit 4765464

Browse files
authored
Merge pull request #409 from govind-kumarr/feature/Qdrant-VectorStore-Integration
Feature/Qdrant vector store integration
2 parents f475594 + ab029a8 commit 4765464

File tree

5 files changed

+296
-0
lines changed

5 files changed

+296
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
2+
import { QdrantClient } from '@qdrant/js-client-rest'
3+
import { QdrantVectorStore, QdrantLibArgs } from 'langchain/vectorstores/qdrant'
4+
import { Embeddings } from 'langchain/embeddings/base'
5+
import { getBaseClasses } from '../../../src/utils'
6+
7+
class Qdrant_Existing_VectorStores implements INode {
8+
label: string
9+
name: string
10+
description: string
11+
type: string
12+
icon: string
13+
category: string
14+
baseClasses: string[]
15+
inputs: INodeParams[]
16+
outputs: INodeOutputsValue[]
17+
18+
constructor() {
19+
this.label = 'Qdrant Load Existing Index'
20+
this.name = 'qdrantExistingIndex'
21+
this.type = 'Qdrant'
22+
this.icon = 'qdrant_logo.svg'
23+
this.category = 'Vector Stores'
24+
this.description = 'Load existing index from Qdrant (i.e., documents have been upserted)'
25+
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
26+
this.inputs = [
27+
{
28+
label: 'Embeddings',
29+
name: 'embeddings',
30+
type: 'Embeddings'
31+
},
32+
{
33+
label: 'Qdrant Server URL',
34+
name: 'qdrantServerUrl',
35+
type: 'string',
36+
placeholder: 'http://localhost:6333'
37+
},
38+
{
39+
label: 'Qdrant Collection Name',
40+
name: 'qdrantCollection',
41+
type: 'string'
42+
},
43+
{
44+
label: 'Qdrant API Key',
45+
name: 'qdrantApiKey',
46+
type: 'password',
47+
optional: true
48+
},
49+
{
50+
label: 'Qdrant Collection Cofiguration',
51+
name: 'qdrantCollectionCofiguration',
52+
type: 'json',
53+
optional: true,
54+
additionalParams: true
55+
},
56+
{
57+
label: 'Top K',
58+
name: 'topK',
59+
description: 'Number of top results to fetch. Default to 4',
60+
placeholder: '4',
61+
type: 'number',
62+
additionalParams: true,
63+
optional: true
64+
}
65+
]
66+
this.outputs = [
67+
{
68+
label: 'Qdrant Retriever',
69+
name: 'retriever',
70+
baseClasses: this.baseClasses
71+
},
72+
{
73+
label: 'Qdrant Vector Store',
74+
name: 'vectorStore',
75+
baseClasses: [this.type, ...getBaseClasses(QdrantVectorStore)]
76+
}
77+
]
78+
}
79+
80+
async init(nodeData: INodeData): Promise<any> {
81+
const qdrantServerUrl = nodeData.inputs?.qdrantServerUrl as string
82+
const collectionName = nodeData.inputs?.qdrantCollection as string
83+
const qdrantApiKey = nodeData.inputs?.qdrantApiKey as string
84+
let qdrantCollectionCofiguration = nodeData.inputs?.qdrantCollectionCofiguration
85+
const embeddings = nodeData.inputs?.embeddings as Embeddings
86+
const output = nodeData.outputs?.output as string
87+
const topK = nodeData.inputs?.topK as string
88+
const k = topK ? parseInt(topK, 10) : 4
89+
90+
// connect to Qdrant Cloud
91+
const client = new QdrantClient({
92+
url: qdrantServerUrl,
93+
apiKey: qdrantApiKey
94+
})
95+
96+
const dbConfig: QdrantLibArgs = {
97+
client,
98+
collectionName
99+
}
100+
101+
if (qdrantCollectionCofiguration) {
102+
qdrantCollectionCofiguration =
103+
typeof qdrantCollectionCofiguration === 'object' ? qdrantCollectionCofiguration : JSON.parse(qdrantCollectionCofiguration)
104+
dbConfig.collectionConfig = qdrantCollectionCofiguration
105+
}
106+
107+
const vectorStore = await QdrantVectorStore.fromExistingCollection(embeddings, dbConfig)
108+
109+
if (output === 'retriever') {
110+
const retriever = vectorStore.asRetriever(k)
111+
return retriever
112+
} else if (output === 'vectorStore') {
113+
;(vectorStore as any).k = k
114+
return vectorStore
115+
}
116+
return vectorStore
117+
}
118+
}
119+
120+
module.exports = { nodeClass: Qdrant_Existing_VectorStores }
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
2+
import { QdrantClient } from '@qdrant/js-client-rest'
3+
import { QdrantVectorStore, QdrantLibArgs } from 'langchain/vectorstores/qdrant'
4+
import { Embeddings } from 'langchain/embeddings/base'
5+
import { Document } from 'langchain/document'
6+
import { getBaseClasses } from '../../../src/utils'
7+
import { flatten } from 'lodash'
8+
9+
class QdrantUpsert_VectorStores implements INode {
10+
label: string
11+
name: string
12+
description: string
13+
type: string
14+
icon: string
15+
category: string
16+
baseClasses: string[]
17+
inputs: INodeParams[]
18+
outputs: INodeOutputsValue[]
19+
20+
constructor() {
21+
this.label = 'Qdrant Upsert Document'
22+
this.name = 'qdrantUpsert'
23+
this.type = 'Qdrant'
24+
this.icon = 'qdrant_logo.svg'
25+
this.category = 'Vector Stores'
26+
this.description = 'Upsert documents to Qdrant'
27+
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
28+
this.inputs = [
29+
{
30+
label: 'Document',
31+
name: 'document',
32+
type: 'Document',
33+
list: true
34+
},
35+
{
36+
label: 'Embeddings',
37+
name: 'embeddings',
38+
type: 'Embeddings'
39+
},
40+
{
41+
label: 'Qdrant Server URL',
42+
name: 'qdrantServerUrl',
43+
type: 'string',
44+
placeholder: 'http://localhost:6333'
45+
},
46+
{
47+
label: 'Qdrant Collection Name',
48+
name: 'qdrantCollection',
49+
type: 'string'
50+
},
51+
{
52+
label: 'Qdrant API Key',
53+
name: 'qdrantApiKey',
54+
type: 'password',
55+
optional: true
56+
},
57+
{
58+
label: 'Top K',
59+
name: 'topK',
60+
description: 'Number of top results to fetch. Default to 4',
61+
placeholder: '4',
62+
type: 'number',
63+
additionalParams: true,
64+
optional: true
65+
}
66+
]
67+
this.outputs = [
68+
{
69+
label: 'Qdrant Retriever',
70+
name: 'retriever',
71+
baseClasses: this.baseClasses
72+
},
73+
{
74+
label: 'Qdrant Vector Store',
75+
name: 'vectorStore',
76+
baseClasses: [this.type, ...getBaseClasses(QdrantVectorStore)]
77+
}
78+
]
79+
}
80+
81+
async init(nodeData: INodeData): Promise<any> {
82+
const qdrantServerUrl = nodeData.inputs?.qdrantServerUrl as string
83+
const collectionName = nodeData.inputs?.qdrantCollection as string
84+
const qdrantApiKey = nodeData.inputs?.qdrantApiKey as string
85+
const docs = nodeData.inputs?.document as Document[]
86+
const embeddings = nodeData.inputs?.embeddings as Embeddings
87+
const output = nodeData.outputs?.output as string
88+
const topK = nodeData.inputs?.topK as string
89+
const k = topK ? parseInt(topK, 10) : 4
90+
91+
// connect to Qdrant Cloud
92+
const client = new QdrantClient({
93+
url: qdrantServerUrl,
94+
apiKey: qdrantApiKey
95+
})
96+
97+
const flattenDocs = docs && docs.length ? flatten(docs) : []
98+
const finalDocs = []
99+
for (let i = 0; i < flattenDocs.length; i += 1) {
100+
finalDocs.push(new Document(flattenDocs[i]))
101+
}
102+
103+
const dbConfig: QdrantLibArgs = {
104+
client,
105+
url: qdrantServerUrl,
106+
collectionName
107+
}
108+
const vectorStore = await QdrantVectorStore.fromDocuments(finalDocs, embeddings, dbConfig)
109+
110+
if (output === 'retriever') {
111+
const retriever = vectorStore.asRetriever(k)
112+
return retriever
113+
} else if (output === 'vectorStore') {
114+
;(vectorStore as any).k = k
115+
return vectorStore
116+
}
117+
return vectorStore
118+
}
119+
}
120+
121+
module.exports = { nodeClass: QdrantUpsert_VectorStores }
Loading

packages/components/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@getzep/zep-js": "^0.3.1",
2121
"@huggingface/inference": "1",
2222
"@pinecone-database/pinecone": "^0.0.12",
23+
"@qdrant/js-client-rest": "^1.2.2",
2324
"@supabase/supabase-js": "^2.21.0",
2425
"@types/js-yaml": "^4.0.5",
2526
"axios": "^0.27.2",

0 commit comments

Comments
 (0)