From c36409d3b84492d819c63861cd8120ed96a06876 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Tue, 9 Sep 2025 01:06:29 +0800 Subject: [PATCH] feat: Expose disableScoringAutoprojection to lancedb Signed-off-by: Xuanwo --- nodejs/lancedb/query.ts | 17 +++++++++++++++++ nodejs/src/query.rs | 16 ++++++++++++++++ rust/lancedb/src/query.rs | 19 +++++++++++++++++++ rust/lancedb/src/remote/table.rs | 3 +++ rust/lancedb/src/table.rs | 4 ++++ 5 files changed, 59 insertions(+) diff --git a/nodejs/lancedb/query.ts b/nodejs/lancedb/query.ts index 2fbe48b8..998b3130 100644 --- a/nodejs/lancedb/query.ts +++ b/nodejs/lancedb/query.ts @@ -363,6 +363,23 @@ export class StandardQueryBase< return this.where(predicate); } + /** + * Disable autoprojection of scoring columns. + * + * When you specify an explicit projection with {@link select} that does not + * include scoring columns (e.g. `_score` for FTS or `_distance` for vector + * search), Lance currently auto-includes those columns and emits a + * deprecation warning. Calling this method disables that behavior so the + * scoring columns are only returned if explicitly selected. + */ + disableScoringAutoprojection(): this { + this.doCall((inner: NativeQueryType) => { + // @ts-expect-error method is present on Query and VectorQuery only + inner.disableScoringAutoprojection(); + }); + return this; + } + fullTextSearch( query: string | FullTextQuery, options?: Partial, diff --git a/nodejs/src/query.rs b/nodejs/src/query.rs index 3a1d441d..b6be4d2c 100644 --- a/nodejs/src/query.rs +++ b/nodejs/src/query.rs @@ -88,6 +88,14 @@ impl Query { self.inner = self.inner.clone().with_row_id(); } + #[napi] + pub fn disable_scoring_autoprojection(&mut self) { + self.inner = self + .inner + .clone() + .disable_scoring_autoprojection(); + } + #[napi(catch_unwind)] pub async fn execute( &self, @@ -265,6 +273,14 @@ impl VectorQuery { self.inner = self.inner.clone().with_row_id(); } + #[napi] + pub fn disable_scoring_autoprojection(&mut self) { + self.inner = self + .inner + .clone() + .disable_scoring_autoprojection(); + } + #[napi] pub fn rerank(&mut self, callbacks: RerankerCallbacks) { self.inner = self diff --git a/rust/lancedb/src/query.rs b/rust/lancedb/src/query.rs index 9663379d..3b5258a9 100644 --- a/rust/lancedb/src/query.rs +++ b/rust/lancedb/src/query.rs @@ -448,6 +448,15 @@ pub trait QueryBase { /// the scores are converted to ranks and then normalized. If "Score", the /// scores are normalized directly. fn norm(self, norm: NormalizeMethod) -> Self; + + /// Disable autoprojection of scoring columns. + /// + /// When an explicit projection is provided that does not include scoring + /// columns (e.g. `_score` for FTS or `_distance` for vector search), the + /// current default behavior is to auto-include those columns and emit a + /// deprecation warning. Calling this adopts the future behavior and avoids + /// the warning. + fn disable_scoring_autoprojection(self) -> Self; } pub trait HasQuery { @@ -507,6 +516,11 @@ impl QueryBase for T { self.mut_query().norm = Some(norm); self } + + fn disable_scoring_autoprojection(mut self) -> Self { + self.mut_query().disable_scoring_autoprojection = true; + self + } } /// Options for controlling the execution of a query @@ -645,6 +659,10 @@ pub struct QueryRequest { /// Configure how query results are normalized when doing hybrid search pub norm: Option, + + /// If true, do not auto-include scoring columns when they are + /// omitted from an explicit projection. + pub disable_scoring_autoprojection: bool, } impl Default for QueryRequest { @@ -660,6 +678,7 @@ impl Default for QueryRequest { prefilter: true, reranker: None, norm: None, + disable_scoring_autoprojection: false, } } } diff --git a/rust/lancedb/src/remote/table.rs b/rust/lancedb/src/remote/table.rs index 8338978a..4b102c50 100644 --- a/rust/lancedb/src/remote/table.rs +++ b/rust/lancedb/src/remote/table.rs @@ -372,6 +372,9 @@ impl RemoteTable { params: &QueryRequest, ) -> Result<()> { body["prefilter"] = params.prefilter.into(); + if params.disable_scoring_autoprojection { + body["disable_scoring_autoprojection"] = serde_json::Value::Bool(true); + } if let Some(offset) = params.offset { body["offset"] = serde_json::Value::Number(serde_json::Number::from(offset)); } diff --git a/rust/lancedb/src/table.rs b/rust/lancedb/src/table.rs index 1bbeed52..79044dcc 100644 --- a/rust/lancedb/src/table.rs +++ b/rust/lancedb/src/table.rs @@ -2331,6 +2331,10 @@ impl BaseTable for NativeTable { scanner.full_text_search(fts.clone())?; } + if query.base.disable_scoring_autoprojection { + scanner.disable_scoring_autoprojection(); + } + if let Some(refine_factor) = query.refine_factor { scanner.refine(refine_factor); }