向量数据库数据库人工智能后端【免费下载链接】lancedbDeveloper-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.项目地址https://gitcode.com/gh_mirrors/la/lancedb点击查看免费下载导读AutoQuery是lancedb/lancedbNode.js SDK 中面向字符串搜索的自动路由查询构建器它不要求开发者预先判断查询应该走全文检索Full-Text Search还是向量搜索Vector Search而是在每次执行时根据当前表版本revision的 schema 元数据动态决定路由。本文将完整讲解AutoQuery的触发入口、路由决策原理、全部可用的查询构建方法与执行/调试 API并结合 query.ts 与 table.ts 的源码实现及 table.test.ts 的测试用例帮助读者掌握同一段搜索代码随表结构变化自动切换检索模式的实战方案。AutoQuery 是什么在 AutoQuery 类文档 中AutoQuery被定义为A builder for automatic string searches. Automatic search determines whether to use full-text or vector search from the table revision selected for each execution. This builder exposes the common operations supported by both query families.即自动字符串搜索构建器。它的核心特征是每次执行时基于所选定的表版本决定使用全文搜索还是向量搜索并对外暴露两类查询族Query与VectorQuery共同支持的通用操作。从继承关系看AutoQuery继承自StandardQueryBaseNativeQuery | NativeVectorQuery见 query.ts因此它天然拥有全文查询与向量查询共享的构建能力其内部持有inner: Query | VectorQuery | PromiseQuery | VectorQuery属性最终真正执行时该属性会被解析为具体的原生查询对象。需要强调的关键点路由决策发生在执行时而非构建时。也就是说即使你在构建查询时表还没有 embedding 元数据只要在真正执行如调用toArray()前表被覆写为携带 embedding 函数的 schema查询就会自动切换为向量搜索反之亦然。这正是automatic一词的含义。触发入口Table.search 与 queryType 分派AutoQuery并非由用户直接new出来构造函数被标记为hidden而是通过Table.search()在默认参数下返回。在 table.ts 中search( query: string | IntoVector | MultiVector | FullTextQuery, queryType: string auto, ftsColumns?: string | string[], ): VectorQuery | Query | AutoQuery其分派逻辑table.ts如下若query不是字符串且不是FullTextQuery实例则视为向量输入直接走vectorSearch(query)若queryType fts返回query().fullTextSearch(query, { columns: ftsColumns })强制全文检索若queryType auto默认值若传入的是FullTextQuery实例如MatchQuery、PhraseQuery等直接构造全文查询否则调用createAutoQuery(...)创建AutoQuery其他queryType如显式vector走nearestTo(queryPromise)其中查询向量由表上注册的 embedding 函数计算若表未定义 embedding 函数则 rejectNo embedding functions are defined in the table对应测试见 table.test.ts。因此最典型的用法就是import * as lancedb from lancedb/lancedb; const db await lancedb.connect(./.lancedb); const table await db.createTable(my_table, [{ text: hello world }]); // 默认 queryType 为 auto返回 AutoQuery const results await table.search(hello).toArray();底层路由原理createAutoQuery 与表快照AutoQuery的路由逻辑实现在createAutoQueryquery.ts其核心是每次执行时对表做一次快照并读取 schema 元数据const snapshotRoute async (): PromiseRouteSnapshot { const snapshot await table.querySnapshot(); const schema tableFromIPC(await snapshot.schema()).schema; return { table: snapshot, embeddingMetadata: schema.metadata.get(embedding_functions), }; };路由判定规则非常直观若表 schema 的元数据中没有embedding_functions则内部构造inner.fullTextSearch({ query, columns })走全文检索若存在embedding_functions则解析 embedding 函数并通过computeQueryEmbeddings(query)计算查询向量然后走nearestToNative(...)的向量搜索。也就是说表上是否注册了 embedding 函数决定了字符串搜索的路由方向。在 table.ts 中embedding 元数据通过getRegistry().parseFunctions(new Map([[embedding_functions, metadata]]))解析并调用首个 embedding 函数的computeQueryEmbeddings生成查询向量当前实现仅支持单个 embedding 函数源码中以TODO: Support multiple embedding functions标注。AutoQuery类本身query.ts使用调用延迟绑定模式实现构建期统一、执行期路由所有链式调用如where、limit、select通过doCall被收集进calls数组而不是立即作用到内部对象每次执行终端操作如toArray、toArrow时getInner()先调用createInner()生成当前路由对应的原生查询再把已收集的全部调用依次apply上去。这样既保证了构建器可以被重复执行每次执行都重新路由又避免了在构建阶段就锁定查询类型。测试 table.test.ts 专门验证了这一点同一个autoQuery对象在表被覆写为带 embedding schema 后执行结果从全文检索语义切换到向量检索语义同时验证了构建器可复用执行时只新增快照调用、embedding 计算有缓存的行为snapshotCalls逐次 1而initCalls/queryCalls保持不增长。通用过滤与排序方法StandardQueryBase 族AutoQuery继承了StandardQueryBase提供的以下通用方法源码见 query.ts这些方法同时被全文查询与向量查询支持where() / filter()以 SQL 字符串作为过滤条件where(predicate: string): this示例table.search(hello).where(x 10).toArray(); table.search(hello).where(y 0 AND y 100).toArray(); table.search(hello).where(x 5 OR y test).toArray();两点使用要点文档明确说明过滤性能可以通过在过滤列上创建标量索引scalar index来提升多次调用where时多个过滤条件以逻辑 AND 合并而不是后者替换前者。底层实现为inner.onlyIf(predicate)见 query.ts。filter()是where的已废弃别名deprecated Use where instead新代码应直接使用where。fullTextSearch()即使在AutoQuery上也可以显式叠加全文搜索约束query.tsfullTextSearch(query: string | FullTextQuery, options?: PartialFullTextSearchOptions): thisquery可以是普通字符串也可以是 FullTextQuery 实例如MatchQuery、PhraseQuery、BoostQuery、MultiMatchQuery、BooleanQuery定义见 query.tsoptions.columns可以是单个字符串或字符串数组指定参与全文检索的列当传入FullTextQuery实例时直接使用其内部定义。limit() 与 offset()limit(limit: number): this offset(offset: number): this默认无 limit文档明确指出普通搜索plain search若不调用limit将返回表中所有合法行而向量搜索则默认limit为 10见 query.ts 中nearestTo的注释。offset用于跳过指定数量的行后再返回结果典型场景是分页。orderBy()按指定列排序query.tsorderBy(ordering: ColumnOrdering | ColumnOrdering[]): thisColumnOrdering见 ColumnOrdering 接口支持columnName、ascending默认true、nullsFirst默认false字段也可传入数组实现多列排序。注意文档在useLsm中提示MemWAL 表上的 LSM 扫描器不支持orderBy此时需配合useLsm(false)使用。fastSearch()fastSearch(): this跳过未索引数据的搜索可显著加快查询速度但会漏掉尚未建立索引的数据。文档明确建议先用 Table#optimize 将全部未索引数据建立索引再考虑使用fastSearch。useLsm()MemWAL 读路由控制useLsm用于控制 MemWAL 表的读取路由query.tsuseLsm(enable: boolean): this其语义如下文档原文要点默认不调用当表带有 MemWAL 写入配置通过 Table#setLsmWriteSpec 设置时读取会路由到 LSM 扫描器从而一并返回通过mergeInsertLSM 路径写入、尚未压实compact进基表的数据包括 active/frozen 内存 memtable 与已刷新的 generation并按主键去重没有该配置的表则直接读取基表。useLsm(true)强制使用 LSM 扫描器若表没有 MemWAL 写入配置则直接报错。useLsm(false)绕过 MemWAL只读取基表即使表带有配置。限制LSM 扫描器不支持所有查询形态如 reranking、hybrid search、orderBy。在 MemWAL 表上使用这些形态时除非设置useLsm(false)否则会报错——因为只读基表会静默丢失尚未压实的 MemWAL 数据。结果控制与执行方法QueryBase 族select()列裁剪与动态列select控制返回列query.tsselect(columns: string | string[] | Recordstring, string | Mapstring, string): this默认返回全部列但这会显著影响延迟。LanceDB 以列式columnar存储可以精细地只读取所需列因此文档强调最佳实践是总是将查询裁剪到所需列传入字符串或字符串数组时只返回这些列传入Mapstring, string或Recordstring, string可创建动态列键为返回列名值为计算该列的 SQL 表达式。例如 SQL 的SELECT a b AS combined, c等价于table.search(hello).select(new Map([[combined, a b], [c, c]])).toArray();列始终按给定顺序返回即使该顺序与写入数据时的列序不同文档提示Recordstring, string对象字面量依赖Object.entries的插入顺序容易出错Map更可靠。withRowId()返回行 IDwithRowId(): this在结果中返回行 ID 列可用于跨查询匹配结果——例如同时执行全文检索与向量检索再依据行 ID 做混合搜索hybrid search的融合。execute() 与迭代execute(options?)返回AsyncGeneratorRecordBatchany即 RecordBatch 的异步迭代器query.ts。文档指出默认情况下 LanceDB 使用多线程计算结果结果集较大时会同时处理多个 batch但这种预读readahead是受限的若消费速度慢会施加背压backpressure从而约束单次查询的最大内存占用。因此流式处理大批量结果时可以直接for await消费。toArray() 与 toArrow()toArray(options?): Promiseany[] // 收集结果为对象数组 toArrow(options?): PromiseArrowTable // 收集结果为 Arrow Table两者均接受可选的QueryExecutionOptions见 QueryExecutionOptions 接口包含maxBatchLength、timeoutMs等执行参数是AutoQuery最常见的终端操作。outputSchema()执行前预览输出结构outputSchema(): PromiseSchemaany返回本次查询将要输出结果的 Arrow Schema可在真正执行前检查返回列的类型与名称query.ts。查询计划调试explainPlan 与 analyzePlan这两个方法对排查查询到底走了哪条路径、消耗在哪非常关键尤其适合验证AutoQuery的路由结果。explainPlan()explainPlan(verbose: boolean false): Promisestring生成查询执行计划的文字说明verbose为true时提供更详细的信息。示例import * as lancedb from lancedb/lancedb; const db await lancedb.connect(./.lancedb); const table await db.createTable(my_table, [ { vector: [1.1, 0.9], id: 1 }, ]); const plan await table.query().nearestTo([0.5, 0.2]).explainPlan();analyzePlan()analyzePlan(distributedMetrics?): Promisestring执行查询并返回带运行时指标runtime metrics的物理查询计划适合性能分析与调试——它展示查询是如何被执行的并包含各步骤的耗时、处理行数、I/O 统计等。参数distributedMetrics类型见 AnalyzePlanDistributedMetrics控制远程查询计划中分布式工作节点指标的展示方式默认值为aggregate聚合。官方文档给出的完整示例输出向量查询路径指标已内联AnalyzeExec verbosetrue, metrics[] ProjectionExec: expr[id3 as id, vector0 as vector, _distance2 as _distance], metrics[output_rows1, elapsed_compute3.292µs] Take: columnsvector, _rowid, _distance, (id), metrics[output_rows1, elapsed_compute66.001µs, batches_processed1, bytes_read8, iops1, requests1] CoalesceBatchesExec: target_batch_size1024, metrics[output_rows1, elapsed_compute3.333µs] GlobalLimitExec: skip0, fetch10, metrics[output_rows1, elapsed_compute167ns] FilterExec: _distance2 IS NOT NULL, metrics[output_rows1, elapsed_compute8.542µs] SortExec: TopK(fetch10), expr[_distance2 ASC NULLS LAST], metrics[output_rows1, elapsed_compute63.25µs, row_replacements1] KNNVectorDistance: metricl2, metrics[output_rows1, elapsed_compute114.333µs, output_batches1] LanceScan: uri/path/to/data, projection[vector], row_idtrue, row_addrfalse, orderedfalse, metrics[output_rows1, elapsed_compute103.626µs, bytes_read549, iops2, requests2]从该输出可以看出向量搜索的完整执行链LanceScan表扫描→KNNVectorDistanceL2 距离计算→SortExecTopK 排序→FilterExec→GlobalLimitExec→CoalesceBatchesExec→Take回取所需列→ProjectionExec。若AutoQuery在无 embedding 元数据的表上路由到全文检索计划树中的KNNVectorDistance会被全文检索相关算子取代因此analyzePlan也是验证自动路由方向的实用手段。实战模式与注意事项综合文档与源码使用AutoQuery时有几个值得注意的实践要点依赖 embedding 元数据自动路由只要表 schema 带有embedding_functions元数据通常通过LanceSchema 注册的EmbeddingFunction创建table.search(文本)就会自动做向量搜索否则退化为全文检索。创建表时使用 embedding 函数生成 schema 的示例可参考 embedding 模块 与LanceSchemaembedding/functions/LanceSchema.md。构建器可复用AutoQuery允许同一个构建器重复执行每次执行重新取表快照并路由适合需要跟随表版本演进的场景配合只读一致性配置如readConsistencyInterval可观察到一致的快照行为。全文检索需要索引无 embedding 表上的自动路由是全文检索若未在文本列创建 FTS 索引Index.fts()检索可能无法返回预期结果创建索引可用 Table#createIndex。明确指定类型需要强制某种检索方式时可在search(query, fts, ftsColumns)或search(query, vector)中显式指定queryType避免依赖自动路由向量检索模式下若表未注册 embedding 函数会直接报错见 table.test.ts。配合 where 与 select 控制开销自动路由本身不改变列式存储的 I/O 优化特性始终建议用select裁剪列、用where收紧范围并用analyzePlan观察各阶段指标。小结AutoQuery是 LanceDB Node.js SDK 中一个查询、两种模式的抽象它以表快照的embedding_functions元数据为路由依据在每次执行时自动在全文检索与向量检索之间切换并把两类查询共有的过滤、排序、分页、列裁剪、行 ID、MemWAL 路由与执行计划调试能力统一暴露给调用方。对于同一份数据既可能带 embedding 又可能不带的动态表结构场景AutoQuery让应用代码无需随表结构变化而改动值得作为字符串搜索的默认入口使用。赞分享向量数据库数据库人工智能后端【免费下载链接】lancedbDeveloper-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.项目地址https://gitcode.com/gh_mirrors/la/lancedb点击查看免费下载相关推荐LanceDB Node.js 查询构建器 Query 类完全指南从向量检索到执行计划分析LanceDB Node.js 查询构建器 Query 类完全指南从向量检索到执行计划分析 本文以 LanceDB 官方 Node.js SDK lanc向量数据库数据库人工智能后端MariaDB 集成指南在 Haystack 中构建基于向量检索与全文检索的 RAG 应用MariaDB 集成指南在 Haystack 中构建基于向量检索与全文检索的 RAG 应用 MariaDB 11.7 原生引入 VECTOR 数据类型与 M人工智能大模型RAGAI AgentNLPLLM Zoomcamp 向量检索进阶路线从文本搜索起步用评估驱动向向量搜索与混合检索演进LLM Zoomcamp 向量检索进阶路线从文本搜索起步用评估驱动向向量搜索与混合检索演进 向量搜索能够按语义匹配文档弥补关键词搜索无法理解换一种说法示例工程教程人工智能大模型创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?