95 lines
3 KiB
TypeScript
95 lines
3 KiB
TypeScript
|
|
/**
|
||
|
|
* Unit tests for FindParams.includeVectors — opt-in vector hydration on find().
|
||
|
|
*
|
||
|
|
* Verifies that find({ includeVectors: true }) returns each result's stored
|
||
|
|
* embedding under entity.vector (matching get({ includeVectors: true })), that
|
||
|
|
* the default keeps the perf contract of an empty vector, and that the
|
||
|
|
* metadata-only find({ where }) path honors the flag too.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||
|
|
import { Brainy } from '../../../src/brainy'
|
||
|
|
import { createTestConfig } from '../../helpers/test-factory'
|
||
|
|
|
||
|
|
describe('FindParams.includeVectors', () => {
|
||
|
|
let brain: Brainy
|
||
|
|
|
||
|
|
beforeEach(async () => {
|
||
|
|
brain = new Brainy(createTestConfig())
|
||
|
|
await brain.init()
|
||
|
|
})
|
||
|
|
|
||
|
|
afterEach(async () => {
|
||
|
|
await brain.close()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('returns the stored vector for query-based find when includeVectors is true', async () => {
|
||
|
|
const id = await brain.add({
|
||
|
|
type: 'document',
|
||
|
|
data: 'machine learning and neural networks',
|
||
|
|
metadata: { topic: 'ai' }
|
||
|
|
})
|
||
|
|
|
||
|
|
// Stored vector, as get() surfaces it — the reference for the find() result.
|
||
|
|
const stored = await brain.get(id, { includeVectors: true })
|
||
|
|
expect(stored!.vector.length).toBeGreaterThan(0)
|
||
|
|
|
||
|
|
const results = await brain.find({
|
||
|
|
query: 'machine learning and neural networks',
|
||
|
|
includeVectors: true,
|
||
|
|
limit: 10
|
||
|
|
})
|
||
|
|
|
||
|
|
const hit = results.find((r) => r.entity.id === id)
|
||
|
|
expect(hit).toBeDefined()
|
||
|
|
expect(hit!.entity.vector.length).toBeGreaterThan(0)
|
||
|
|
expect(hit!.entity.vector).toEqual(stored!.vector)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('returns an empty vector by default (perf contract preserved)', async () => {
|
||
|
|
const id = await brain.add({
|
||
|
|
type: 'document',
|
||
|
|
data: 'default path should not hydrate vectors',
|
||
|
|
metadata: { topic: 'perf' }
|
||
|
|
})
|
||
|
|
|
||
|
|
const results = await brain.find({
|
||
|
|
query: 'default path should not hydrate vectors',
|
||
|
|
limit: 10
|
||
|
|
})
|
||
|
|
|
||
|
|
const hit = results.find((r) => r.entity.id === id)
|
||
|
|
expect(hit).toBeDefined()
|
||
|
|
expect(hit!.entity.vector.length).toBe(0)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('honors includeVectors on the metadata-only where path', async () => {
|
||
|
|
const id = await brain.add({
|
||
|
|
type: 'thing',
|
||
|
|
data: 'metadata only filter target',
|
||
|
|
metadata: { category: 'filtered' }
|
||
|
|
})
|
||
|
|
|
||
|
|
const stored = await brain.get(id, { includeVectors: true })
|
||
|
|
|
||
|
|
const withVectors = await brain.find({
|
||
|
|
where: { category: 'filtered' },
|
||
|
|
includeVectors: true,
|
||
|
|
limit: 10
|
||
|
|
})
|
||
|
|
const hit = withVectors.find((r) => r.entity.id === id)
|
||
|
|
expect(hit).toBeDefined()
|
||
|
|
expect(hit!.entity.vector.length).toBeGreaterThan(0)
|
||
|
|
expect(hit!.entity.vector).toEqual(stored!.vector)
|
||
|
|
|
||
|
|
// And the same filter without the flag stays empty.
|
||
|
|
const withoutVectors = await brain.find({
|
||
|
|
where: { category: 'filtered' },
|
||
|
|
limit: 10
|
||
|
|
})
|
||
|
|
const plainHit = withoutVectors.find((r) => r.entity.id === id)
|
||
|
|
expect(plainHit).toBeDefined()
|
||
|
|
expect(plainHit!.entity.vector.length).toBe(0)
|
||
|
|
})
|
||
|
|
})
|