Skip to content

Commit c287db2

Browse files
committed
add indexName and embeddingFieldPath
1 parent 05dbbb1 commit c287db2

File tree

2 files changed

+101
-98
lines changed

2 files changed

+101
-98
lines changed

src/core/IndexManager.js

Lines changed: 95 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -3,110 +3,108 @@ import debug from 'debug';
33
const log = debug('mongodb-rag:index');
44

55
class IndexManager {
6-
constructor(collection, options = {}) {
7-
this.collection = collection;
8-
this.options = {
9-
indexName: options.indexName || 'default',
10-
dimensions: options.dimensions || 1536,
11-
similarity: options.similarity || 'cosine',
12-
...options
13-
};
14-
}
15-
16-
async ensureIndexes() {
17-
try {
18-
log("Checking indexes...");
19-
await this.createSupportingIndexes(); // Ensure only supporting indexes
20-
log("All indexes verified");
21-
} catch (error) {
22-
throw new Error(`Failed to ensure indexes: ${error.message}`);
6+
constructor(collection, options = {}) {
7+
this.collection = collection;
8+
this.options = {
9+
indexName: options.indexName || 'default',
10+
dimensions: options.dimensions || 1536,
11+
similarity: options.similarity || 'cosine',
12+
...options
13+
};
2314
}
24-
}
25-
26-
async createSupportingIndexes() {
27-
try {
28-
// Index for fast document lookups
29-
await this.collection.createIndex(
30-
{ documentId: 1 },
31-
{ name: 'document_lookup' }
32-
);
33-
34-
// Index for metadata filtering
35-
await this.collection.createIndex(
36-
{ 'metadata.source': 1, 'metadata.category': 1 },
37-
{ name: 'metadata_filter', sparse: true }
38-
);
39-
40-
log('Supporting indexes created successfully');
41-
} catch (error) {
42-
throw new Error(`Failed to create supporting indexes: ${error.message}`);
43-
}
44-
}
45-
46-
buildSearchQuery(embedding, filter = {}, options = {}) {
47-
const vectorSearchQuery = {
48-
index: this.options.indexName,
49-
path: "embedding",
50-
queryVector: embedding,
51-
limit: options.maxResults || 10,
52-
exact: options.exact || false // Allow exact to be configurable
53-
};
54-
55-
// Only add numCandidates if exact is false
56-
if (!vectorSearchQuery.exact) {
57-
vectorSearchQuery.numCandidates = options.numCandidates || 100;
15+
16+
async ensureIndexes() {
17+
try {
18+
log("Checking indexes...");
19+
await this.createSupportingIndexes(); // Ensure only supporting indexes
20+
log("All indexes verified");
21+
} catch (error) {
22+
throw new Error(`Failed to ensure indexes: ${error.message}`);
23+
}
5824
}
59-
60-
const pipeline = [
61-
{
62-
$vectorSearch: vectorSearchQuery
63-
},
64-
{
65-
$addFields: {
66-
score: { $meta: "searchScore" }
25+
26+
async createSupportingIndexes() {
27+
try {
28+
// Index for fast document lookups
29+
await this.collection.createIndex(
30+
{ documentId: 1 },
31+
{ name: 'document_lookup' }
32+
);
33+
34+
// Index for metadata filtering
35+
await this.collection.createIndex(
36+
{ 'metadata.source': 1, 'metadata.category': 1 },
37+
{ name: 'metadata_filter', sparse: true }
38+
);
39+
40+
log('Supporting indexes created successfully');
41+
} catch (error) {
42+
throw new Error(`Failed to create supporting indexes: ${error.message}`);
6743
}
68-
}
69-
];
70-
71-
// Add filter if present
72-
if (Object.keys(filter).length > 0) {
73-
pipeline[0].$vectorSearch.filter = filter;
7444
}
75-
76-
if (options.includeMetadata) {
77-
pipeline.push({
78-
$project: {
79-
documentId: 1,
80-
content: 1,
81-
metadata: 1,
82-
score: 1
45+
46+
buildSearchQuery(embedding, filter = {}, options = {}) {
47+
const vectorSearchQuery = {
48+
index: this.indexName, // <-- Use configured index name
49+
path: this.embeddingFieldPath, // <-- Use configured embedding field path
50+
queryVector: embedding,
51+
limit: options.maxResults || 10,
52+
exact: options.exact || false
53+
};
54+
55+
if (!vectorSearchQuery.exact) {
56+
vectorSearchQuery.numCandidates = options.numCandidates || 100;
57+
}
58+
59+
const pipeline = [
60+
{
61+
$vectorSearch: vectorSearchQuery
62+
},
63+
{
64+
$addFields: {
65+
score: { $meta: "searchScore" }
66+
}
67+
}
68+
];
69+
70+
if (Object.keys(filter).length > 0) {
71+
pipeline[0].$vectorSearch.filter = filter;
8372
}
84-
});
73+
74+
if (options.includeMetadata) {
75+
pipeline.push({
76+
$project: {
77+
documentId: 1,
78+
content: 1,
79+
metadata: 1,
80+
score: 1
81+
}
82+
});
83+
}
84+
85+
console.log('Generated search query:', JSON.stringify(pipeline, null, 2));
86+
return pipeline;
8587
}
86-
87-
console.log('Generated search query:', JSON.stringify(pipeline, null, 2));
88-
return pipeline;
89-
}
90-
91-
92-
async getIndexStats() {
93-
try {
94-
const stats = await this.collection.stats();
95-
const indexes = await this.collection.listIndexes().toArray();
96-
97-
return {
98-
documentCount: stats.count,
99-
indexSize: stats.totalIndexSize,
100-
indexes: indexes.map(index => ({
101-
name: index.name,
102-
size: stats.indexSizes[index.name],
103-
fields: Object.keys(index.key)
104-
}))
105-
};
106-
} catch (error) {
107-
throw new Error(`Failed to get index stats: ${error.message}`);
88+
89+
90+
async getIndexStats() {
91+
try {
92+
const stats = await this.collection.stats();
93+
const indexes = await this.collection.listIndexes().toArray();
94+
95+
return {
96+
documentCount: stats.count,
97+
indexSize: stats.totalIndexSize,
98+
indexes: indexes.map(index => ({
99+
name: index.name,
100+
size: stats.indexSizes[index.name],
101+
fields: Object.keys(index.key)
102+
}))
103+
};
104+
} catch (error) {
105+
throw new Error(`Failed to get index stats: ${error.message}`);
106+
}
108107
}
109-
}
110108
}
111109

112110
export default IndexManager;

src/core/MongoRAG.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class MongoRAG {
3737
mongoUrl: config.mongoUrl,
3838
defaultDatabase: config.database,
3939
defaultCollection: config.collection,
40+
indexName: config.indexName || "vector_index", // <-- Ensure we allow index configuration
41+
embeddingFieldPath: config.embeddingFieldPath || "embedding", // <-- Allow setting embedding field path
4042
embedding: {
4143
provider: config.embedding?.provider || 'openai',
4244
apiKey: config.embedding.apiKey,
@@ -50,6 +52,7 @@ class MongoRAG {
5052
maxResults: config.search?.maxResults || 5
5153
}
5254
};
55+
5356

5457
this.client = null;
5558
this.indexManager = null;
@@ -135,6 +138,8 @@ class MongoRAG {
135138
const embedding = await this._getEmbedding(query);
136139

137140
const indexManager = new IndexManager(col, {
141+
indexName: this.config.indexName, // <-- Pass configured index name
142+
embeddingFieldPath: this.config.embeddingFieldPath, // <-- Pass embedding field path
138143
dimensions: this.config.embedding.dimensions
139144
});
140145

@@ -193,7 +198,7 @@ class MongoRAG {
193198
* @param {string} text - The text to embed.
194199
* @returns {Promise<Array<number>>} The embedded text.
195200
*/
196-
201+
197202
async _getEmbedding(text) {
198203
if (!this.embeddingProvider) {
199204
await this._initializeEmbeddingProvider();

0 commit comments

Comments
 (0)