fix: add keyword index for type field to fix Qdrant codebase_search error (#8964)

Co-authored-by: Roo Code <roomote@roocode.com>
This commit is contained in:
roomote[bot] 2025-11-01 13:20:56 -04:00 committed by GitHub
parent eb68c65296
commit 89d67efc6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 13 deletions

View file

@ -542,14 +542,18 @@ describe("QdrantVectorStore", () => {
})
expect(mockQdrantClientInstance.deleteCollection).not.toHaveBeenCalled()
// Verify payload index creation
// Verify payload index creation - 'type' field first, then pathSegments
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: "type",
field_schema: "keyword",
})
for (let i = 0; i <= 4; i++) {
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: `pathSegments.${i}`,
field_schema: "keyword",
})
}
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
})
it("should not create a new collection if one exists with matching vectorSize and return false", async () => {
// Mock getCollection to return existing collection info with matching vector size
@ -572,14 +576,18 @@ describe("QdrantVectorStore", () => {
expect(mockQdrantClientInstance.createCollection).not.toHaveBeenCalled()
expect(mockQdrantClientInstance.deleteCollection).not.toHaveBeenCalled()
// Verify payload index creation still happens
// Verify payload index creation still happens - 'type' field first, then pathSegments
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: "type",
field_schema: "keyword",
})
for (let i = 0; i <= 4; i++) {
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: `pathSegments.${i}`,
field_schema: "keyword",
})
}
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
})
it("should recreate collection if it exists but vectorSize mismatches and return true", async () => {
const differentVectorSize = 768
@ -625,14 +633,18 @@ describe("QdrantVectorStore", () => {
},
})
// Verify payload index creation
// Verify payload index creation - 'type' field first, then pathSegments
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: "type",
field_schema: "keyword",
})
for (let i = 0; i <= 4; i++) {
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledWith(expectedCollectionName, {
field_name: `pathSegments.${i}`,
field_schema: "keyword",
})
}
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
;(console.warn as any).mockRestore() // Restore console.warn
})
it("should log warning for non-404 errors but still create collection", async () => {
@ -646,7 +658,7 @@ describe("QdrantVectorStore", () => {
expect(mockQdrantClientInstance.getCollection).toHaveBeenCalledTimes(1)
expect(mockQdrantClientInstance.createCollection).toHaveBeenCalledTimes(1)
expect(mockQdrantClientInstance.deleteCollection).not.toHaveBeenCalled()
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
expect(console.warn).toHaveBeenCalledWith(
expect.stringContaining(`Warning during getCollectionInfo for "${expectedCollectionName}"`),
genericError.message,
@ -693,11 +705,16 @@ describe("QdrantVectorStore", () => {
expect(result).toBe(true)
expect(mockQdrantClientInstance.createCollection).toHaveBeenCalledTimes(1)
// Verify all payload index creations were attempted
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
// Verify all payload index creations were attempted (6: type + 5 pathSegments)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
// Verify warnings were logged for each failed index
expect(console.warn).toHaveBeenCalledTimes(5)
// Verify warnings were logged for each failed index (now 6)
expect(console.warn).toHaveBeenCalledTimes(6)
// Verify warning for 'type' index
expect(console.warn).toHaveBeenCalledWith(
expect.stringContaining(`Could not create payload index for type`),
indexError.message,
)
for (let i = 0; i <= 4; i++) {
expect(console.warn).toHaveBeenCalledWith(
expect.stringContaining(`Could not create payload index for pathSegments.${i}`),
@ -826,7 +843,7 @@ describe("QdrantVectorStore", () => {
expect(mockQdrantClientInstance.getCollection).toHaveBeenCalledTimes(2)
expect(mockQdrantClientInstance.deleteCollection).toHaveBeenCalledTimes(1)
expect(mockQdrantClientInstance.createCollection).toHaveBeenCalledTimes(1)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
;(console.warn as any).mockRestore()
})
@ -923,7 +940,7 @@ describe("QdrantVectorStore", () => {
on_disk: true,
},
})
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(5)
expect(mockQdrantClientInstance.createPayloadIndex).toHaveBeenCalledTimes(6)
;(console.warn as any).mockRestore()
})

View file

@ -296,6 +296,23 @@ export class QdrantVectorStore implements IVectorStore {
* Creates payload indexes for the collection, handling errors gracefully.
*/
private async _createPayloadIndexes(): Promise<void> {
// Create index for the 'type' field to enable metadata filtering
try {
await this.client.createPayloadIndex(this.collectionName, {
field_name: "type",
field_schema: "keyword",
})
} catch (indexError: any) {
const errorMessage = (indexError?.message || "").toLowerCase()
if (!errorMessage.includes("already exists")) {
console.warn(
`[QdrantVectorStore] Could not create payload index for type on ${this.collectionName}. Details:`,
indexError?.message || indexError,
)
}
}
// Create indexes for pathSegments fields
for (let i = 0; i <= 4; i++) {
try {
await this.client.createPayloadIndex(this.collectionName, {