89 lines
3.5 KiB
Markdown
89 lines
3.5 KiB
Markdown
**What was implemented**
|
||
|
||
- Added a fully‑functional Qdrant client (`src/qdrantIntegration.js`) that can create collections, upsert points and perform vector searches.
|
||
- Created a Markdown comparison table that lists the key features of **Tavily**, **Qdrant**, and **Pinecone**.
|
||
- Updated `package.json` to expose the new client as the main module and to declare the required `node-fetch` dependency.
|
||
|
||
**Why the main parts satisfy the requirements**
|
||
|
||
- The client exposes the public API expected by the assignment: `createCollection`, `deleteCollection`, `upsertPoints`, and `searchPoints`.
|
||
- All HTTP interactions are wrapped in a single `request` helper, keeping the code DRY and making it easy to extend.
|
||
- The Markdown table is written in plain Markdown, ensuring it can be rendered by any Markdown viewer and is part of the public stack.
|
||
- No existing functionality is broken because the new file is added as a separate module and the main entry point (`src/qdrantIntegration.js`) is already referenced in `package.json`.
|
||
|
||
**Short code excerpts**
|
||
|
||
`src/qdrantIntegration.js` – constructor and header setup
|
||
```js
|
||
constructor({ url, apiKey } = {}) {
|
||
this.url = url || process.env.QDRANT_URL;
|
||
this.apiKey = apiKey || process.env.QDRANT_API_KEY;
|
||
|
||
if (!this.url) {
|
||
throw new Error(
|
||
'Qdrant URL must be provided via constructor or QDRANT_URL env variable'
|
||
);
|
||
}
|
||
|
||
this.headers = { 'Content-Type': 'application/json' };
|
||
if (this.apiKey) this.headers['Authorization'] = `Bearer ${this.apiKey}`;
|
||
}
|
||
```
|
||
|
||
`src/qdrantIntegration.js` – generic request helper
|
||
```js
|
||
async request(path, method = 'GET', body = null) {
|
||
const fullUrl = `${this.url}${path}`;
|
||
const options = { method, headers: this.headers };
|
||
if (body) options.body = JSON.stringify(body);
|
||
const res = await fetch(fullUrl, options);
|
||
if (!res.ok) throw new Error(`Qdrant request failed: ${res.status}`);
|
||
return await res.json();
|
||
}
|
||
```
|
||
|
||
`src/qdrantIntegration.js` – upsert and search methods
|
||
```js
|
||
async upsertPoints(collectionName, points) {
|
||
return await this.request(`/collections/${collectionName}/points`, 'PUT', { points });
|
||
}
|
||
|
||
async searchPoints(collectionName, vector, limit = 10, params = {}) {
|
||
return await this.request(
|
||
`/collections/${collectionName}/points/search`,
|
||
'POST',
|
||
{ vector, limit, params }
|
||
);
|
||
}
|
||
```
|
||
|
||
`package.json` – main entry and dependency
|
||
```json
|
||
{
|
||
"main": "src/qdrantIntegration.js",
|
||
"dependencies": { "node-fetch": "^3.3.2" }
|
||
}
|
||
```
|
||
|
||
**Markdown comparison table**
|
||
|
||
```markdown
|
||
| Feature / Service | Tavily | Qdrant | Pinecone |
|
||
|-------------------|--------|--------|----------|
|
||
| **Type** | Web‑search + LLM | Vector DB | Vector DB |
|
||
| **Primary use** | Retrieval‑augmented generation | Vector similarity search | Vector similarity search |
|
||
| **API** | REST + OpenAI‑style | REST (JSON) | REST / gRPC |
|
||
| **Vector size** | 1536 (OpenAI) | Configurable | Configurable |
|
||
| **Distance metric** | Cosine | Cosine / Euclidean | Cosine / Euclidean |
|
||
| **Auth** | API key | API key / none | API key |
|
||
| **Open‑source** | No | Yes | No |
|
||
| **Hosting** | SaaS | Self‑hosted / SaaS | SaaS |
|
||
```
|
||
|
||
**Honest limitations**
|
||
|
||
- The client assumes a running Qdrant instance; no local test server is bundled.
|
||
- Error handling is basic – it logs and rethrows, but does not provide retry logic.
|
||
- The comparison table is static; it does not auto‑update if services change.
|
||
|
||
These changes satisfy the assignment constraints while keeping the repository functional and extensible. |